diff --git a/backend/database/migrations.go b/backend/database/migrations.go index 2ab548f58..707a5d40b 100644 --- a/backend/database/migrations.go +++ b/backend/database/migrations.go @@ -5,7 +5,6 @@ import ( "fmt" adaudit_domain "github.com/utmstack/utmstack/backend/modules/adaudit/domain" - threatintel_domain "github.com/utmstack/utmstack/backend/modules/threatintel/domain" alerts_domain "github.com/utmstack/utmstack/backend/modules/alerts/domain" appconfig_domain "github.com/utmstack/utmstack/backend/modules/appconfig/domain" audit_domain "github.com/utmstack/utmstack/backend/modules/audit/domain" @@ -20,6 +19,7 @@ import ( arr_domain "github.com/utmstack/utmstack/backend/modules/soar/domain" socai_domain "github.com/utmstack/utmstack/backend/modules/socai/domain" tenant_domain "github.com/utmstack/utmstack/backend/modules/tenant/domain" + threatintel_domain "github.com/utmstack/utmstack/backend/modules/threatintel/domain" "github.com/utmstack/utmstack/backend/pkg/joblease" "gorm.io/gorm" @@ -69,6 +69,8 @@ func Models() []any { dashboards_domain.DashboardFilter{}, loganalyzer_domain.SavedQuery{}, adaudit_domain.ADUser{}, + adaudit_domain.IdentityAlias{}, + adaudit_domain.IdentityAliasAssignment{}, threatintel_domain.AnalystConversation{}, } } diff --git a/backend/migrations/000004_adaudit_write.down.sql b/backend/migrations/000004_adaudit_write.down.sql new file mode 100644 index 000000000..e060716e8 --- /dev/null +++ b/backend/migrations/000004_adaudit_write.down.sql @@ -0,0 +1,2 @@ +DELETE FROM role_permission WHERE role_id = '00000000-0000-0000-0000-00000000a001' AND permission_name = 'adaudit.write'; +DELETE FROM permissions WHERE name = 'adaudit.write'; diff --git a/backend/migrations/000004_adaudit_write.up.sql b/backend/migrations/000004_adaudit_write.up.sql new file mode 100644 index 000000000..1c5a2e562 --- /dev/null +++ b/backend/migrations/000004_adaudit_write.up.sql @@ -0,0 +1,11 @@ +-- Identity aliases (operator-named, one link per account) need a write +-- permission. The init migration seeded adaudit.read only, and 000001 has +-- already run on every live install, so the new row lands here instead. +-- Idempotent on both fresh and upgraded databases. +INSERT INTO permissions (name, description) VALUES + ('adaudit.write', 'Create and manage identity aliases in the audited user inventory') +ON CONFLICT (name) DO NOTHING; + +INSERT INTO role_permission (role_id, permission_name) +SELECT '00000000-0000-0000-0000-00000000a001', 'adaudit.write' +ON CONFLICT DO NOTHING; diff --git a/backend/migrations/000005_identity_alias.down.sql b/backend/migrations/000005_identity_alias.down.sql new file mode 100644 index 000000000..f4a15d49c --- /dev/null +++ b/backend/migrations/000005_identity_alias.down.sql @@ -0,0 +1,6 @@ +DROP INDEX IF EXISTS idx_identity_alias_tenant_name; +ALTER TABLE identity_alias_assignment + DROP CONSTRAINT IF EXISTS fk_identity_alias_assignment_user, + DROP CONSTRAINT IF EXISTS fk_identity_alias_assignment_alias; +DROP TABLE IF EXISTS identity_alias_assignment; +DROP TABLE IF EXISTS identity_alias; diff --git a/backend/migrations/000005_identity_alias.up.sql b/backend/migrations/000005_identity_alias.up.sql new file mode 100644 index 000000000..0529924d4 --- /dev/null +++ b/backend/migrations/000005_identity_alias.up.sql @@ -0,0 +1,15 @@ +-- The identity alias tables are created by GORM AutoMigrate (see +-- database.Models), which cannot express two things this feature needs: +-- * names are unique case-insensitively per tenant -> functional index, +-- * assignments cascade from both ends -> FK constraints. +-- Idempotent on both fresh and upgraded databases. +CREATE UNIQUE INDEX IF NOT EXISTS idx_identity_alias_tenant_name + ON identity_alias (tenant_id, lower(name)); + +ALTER TABLE identity_alias_assignment + DROP CONSTRAINT IF EXISTS fk_identity_alias_assignment_alias, + DROP CONSTRAINT IF EXISTS fk_identity_alias_assignment_user, + ADD CONSTRAINT fk_identity_alias_assignment_alias + FOREIGN KEY (alias_id) REFERENCES identity_alias (id) ON DELETE CASCADE, + ADD CONSTRAINT fk_identity_alias_assignment_user + FOREIGN KEY (user_id) REFERENCES ad_user (id) ON DELETE CASCADE; diff --git a/backend/migrations/000006_adaudit_write_for_user_writers.down.sql b/backend/migrations/000006_adaudit_write_for_user_writers.down.sql new file mode 100644 index 000000000..130249ca0 --- /dev/null +++ b/backend/migrations/000006_adaudit_write_for_user_writers.down.sql @@ -0,0 +1,10 @@ +-- Reverse the 000006 grant. Cannot reconstruct who had users.write at +-- migration time, so strip adaudit.write from every role that has it +-- alongside users.write now. +DELETE FROM role_permission rp +WHERE rp.permission_name = 'adaudit.write' + AND EXISTS ( + SELECT 1 FROM role_permission u + WHERE u.role_id = rp.role_id + AND u.permission_name = 'users.write' + ); diff --git a/backend/migrations/000006_adaudit_write_for_user_writers.up.sql b/backend/migrations/000006_adaudit_write_for_user_writers.up.sql new file mode 100644 index 000000000..0262e8352 --- /dev/null +++ b/backend/migrations/000006_adaudit_write_for_user_writers.up.sql @@ -0,0 +1,9 @@ +-- Users who can write users (users.write) should also be able to write +-- identity aliases (adaudit.write) — same trust level. Grants the permission +-- to every role that holds users.write, so the effect is on all users +-- assigned those roles at migration time. Idempotent. +INSERT INTO role_permission (role_id, permission_name) +SELECT r.role_id, 'adaudit.write' +FROM role_permission r +WHERE r.permission_name = 'users.write' +ON CONFLICT DO NOTHING; diff --git a/backend/modules/adaudit/connectors/connectors.go b/backend/modules/adaudit/connectors/connectors.go index 7309aeebe..a9631e0a6 100644 --- a/backend/modules/adaudit/connectors/connectors.go +++ b/backend/modules/adaudit/connectors/connectors.go @@ -3,6 +3,8 @@ package connectors import ( "context" + "github.com/google/uuid" + "github.com/utmstack/utmstack/backend/modules/adaudit/domain" "github.com/utmstack/utmstack/backend/modules/adaudit/dto" "github.com/utmstack/utmstack/backend/pkg/database" @@ -10,7 +12,7 @@ import ( type ADUserRepository interface { Upsert(ctx context.Context, users []domain.ADUser) error - List(ctx context.Context, f dto.ADUserFilter) ([]domain.ADUser, int64, error) + List(ctx context.Context, f dto.ADUserFilter) ([]dto.UserRow, int64, error) Each(ctx context.Context, source string, fn func(domain.ADUser) error) error Stats(ctx context.Context) (*dto.ADUserStats, error) ResolveLinuxIdentity(ctx context.Context, tenantID, hostname, machineID string) (int64, error) @@ -18,8 +20,27 @@ type ADUserRepository interface { type ADUserUsecase interface { Ingest(ctx context.Context, req dto.IngestRequest) (int, error) - List(ctx context.Context, f dto.ADUserFilter) (*database.List[domain.ADUser], error) + List(ctx context.Context, f dto.ADUserFilter) (*database.List[dto.UserRow], error) Each(ctx context.Context, source string, fn func(domain.ADUser) error) error Stats(ctx context.Context) (*dto.ADUserStats, error) ResolveLinuxIdentity(ctx context.Context, req dto.ResolveLinuxIdentityRequest) (int64, error) } + +type IdentityRepository interface { + Create(ctx context.Context, name, actor string) (*domain.IdentityAlias, error) + List(ctx context.Context, search string) ([]dto.IdentityListItem, error) + Get(ctx context.Context, id uuid.UUID) (*domain.IdentityAlias, error) + Users(ctx context.Context, id uuid.UUID) ([]dto.UserRow, error) + Delete(ctx context.Context, id uuid.UUID) (int, error) + Assign(ctx context.Context, userID, aliasID uuid.UUID, actor string) error + Unassign(ctx context.Context, userID uuid.UUID, actor string) error +} + +type IdentityUsecase interface { + Create(ctx context.Context, name, actor string) (*dto.IdentityResponse, error) + List(ctx context.Context, search string) ([]dto.IdentityListItem, error) + Detail(ctx context.Context, id uuid.UUID) (*dto.IdentityDetail, error) + Delete(ctx context.Context, id uuid.UUID) (int, error) + Assign(ctx context.Context, userID, aliasID uuid.UUID, actor string) error + Unassign(ctx context.Context, userID uuid.UUID, actor string) error +} diff --git a/backend/modules/adaudit/domain/identity_alias.go b/backend/modules/adaudit/domain/identity_alias.go new file mode 100644 index 000000000..d45a12769 --- /dev/null +++ b/backend/modules/adaudit/domain/identity_alias.go @@ -0,0 +1,34 @@ +package domain + +import ( + "strings" + "time" + + "github.com/google/uuid" +) + +type IdentityAlias struct { + ID uuid.UUID `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id"` + TenantID uuid.UUID `gorm:"column:tenant_id;size:36;not null;index:idx_identity_alias_tenant,priority:1" json:"tenantId"` + Name string `gorm:"column:name;size:64;not null" json:"name"` + CreatedBy string `gorm:"column:created_by;size:150;not null" json:"createdBy"` + CreatedAt time.Time `gorm:"column:created_at;not null;default:now()" json:"createdAt"` + Assignments []IdentityAliasAssignment `gorm:"foreignKey:AliasID;references:ID;constraint:false" json:"-"` +} + +func (IdentityAlias) TableName() string { return "identity_alias" } + +func ValidIdentityName(name string) bool { + trimmed := strings.TrimSpace(name) + runess := []rune(trimmed) + return len(runess) >= 2 && len(runess) <= 64 +} + +type IdentityAliasAssignment struct { + AliasID uuid.UUID `gorm:"column:alias_id;type:uuid;primaryKey" json:"aliasId"` + UserID uuid.UUID `gorm:"column:user_id;type:uuid;primaryKey;uniqueIndex:idx_identity_alias_assignment_user" json:"userId"` + AssignedBy string `gorm:"column:assigned_by;size:150;not null" json:"assignedBy"` + AssignedAt time.Time `gorm:"column:assigned_at;not null;default:now()" json:"assignedAt"` +} + +func (IdentityAliasAssignment) TableName() string { return "identity_alias_assignment" } diff --git a/backend/modules/adaudit/domain/identity_alias_test.go b/backend/modules/adaudit/domain/identity_alias_test.go new file mode 100644 index 000000000..bdfd64d1d --- /dev/null +++ b/backend/modules/adaudit/domain/identity_alias_test.go @@ -0,0 +1,21 @@ +package domain + +import "testing" + +func TestValidIdentityName(t *testing.T) { + valid := []string{" ops ", "ops-team", "ab"} + invalid := []string{"", " ", "a ", "a", "b"} + for _, name := range valid { + if !ValidIdentityName(name) { + t.Errorf("ValidIdentityName(%q) = false, want true", name) + } + } + for _, name := range invalid { + if ValidIdentityName(name) { + t.Errorf("ValidIdentityName(%q) = true, want false", name) + } + } + if ValidIdentityName(string(make([]rune, 65))) { + t.Error("a 65-char name is too long") + } +} diff --git a/backend/modules/adaudit/dto/ad_user.go b/backend/modules/adaudit/dto/ad_user.go index ab878e365..7abb7a9f7 100644 --- a/backend/modules/adaudit/dto/ad_user.go +++ b/backend/modules/adaudit/dto/ad_user.go @@ -28,11 +28,12 @@ type IngestRequest struct { } type ADUserFilter struct { - Search string `form:"search"` // substring on samAccountName/sid - Source string `form:"source"` // "windows"|"linux"|"o365"|"azure"|"gcp"|"aws"|"" (all) - Active *bool `form:"active"` - Status string `form:"status"` // active|disabled|deleted|stale|service — overrides Active when set - Sort string `form:"sort"` // recent (last_seen desc) | name (default, samAccountName asc) + Search string `form:"search"` // substring on samAccountName/sid + Source string `form:"source"` // "windows"|"linux"|"o365"|"azure"|"gcp"|"aws"|"" (all) + Active *bool `form:"active"` + Status string `form:"status"` // active|disabled|deleted|stale|service — overrides Active when set + Sort string `form:"sort"` // recent (last_seen desc) | name (default, samAccountName asc) + Identity string `form:"identity"` // a UUID filters to users assigned to that identity; the literal "none" to users without one database.Params } @@ -51,15 +52,17 @@ type SourceCount struct { } type ADUserStats struct { - Total int64 `json:"total"` - Active int64 `json:"active"` - Disabled int64 `json:"disabled"` - Deleted int64 `json:"deleted"` - Stale int64 `json:"stale"` - Service int64 `json:"service"` - Seen24h int64 `json:"seen_24h"` - BySource SourceCount `json:"by_source"` - ByDomain []DomainCount `json:"by_domain"` + Total int64 `json:"total"` + Active int64 `json:"active"` + Disabled int64 `json:"disabled"` + Deleted int64 `json:"deleted"` + Stale int64 `json:"stale"` + Service int64 `json:"service"` + Seen24h int64 `json:"seen_24h"` + Identities int64 `json:"identities"` + Unassigned int64 `json:"unassigned"` + BySource SourceCount `json:"by_source"` + ByDomain []DomainCount `json:"by_domain"` } type ResolveLinuxIdentityRequest struct { diff --git a/backend/modules/adaudit/dto/identity_alias.go b/backend/modules/adaudit/dto/identity_alias.go new file mode 100644 index 000000000..5531079ba --- /dev/null +++ b/backend/modules/adaudit/dto/identity_alias.go @@ -0,0 +1,40 @@ +package dto + +import ( + "time" + + "github.com/utmstack/utmstack/backend/modules/adaudit/domain" +) + +type CreateIdentityRequest struct { + Name string `json:"name"` +} + +type IdentityResponse struct { + ID string `json:"id"` + Name string `json:"name"` + CreatedAt time.Time `json:"createdAt"` +} + +type IdentityListItem struct { + ID string `json:"id"` + Name string `json:"name"` + CreatedAt time.Time `json:"createdAt"` + Count int `json:"count"` +} + +type IdentityDetail struct { + ID string `json:"id"` + Name string `json:"name"` + CreatedAt time.Time `json:"createdAt"` + Users []UserRow `json:"users"` +} + +type UserRow struct { + domain.ADUser + Identity *string `json:"identity"` +} + +type AssignIdentityRequest struct { + IdentityID string `json:"identityId"` +} diff --git a/backend/modules/adaudit/handler/ad_user.go b/backend/modules/adaudit/handler/ad_user.go index fccea5d81..e5c6ea8c6 100644 --- a/backend/modules/adaudit/handler/ad_user.go +++ b/backend/modules/adaudit/handler/ad_user.go @@ -8,6 +8,7 @@ import ( "github.com/utmstack/utmstack/backend/modules/adaudit/domain" "github.com/gin-gonic/gin" + "github.com/google/uuid" "github.com/threatwinds/go-sdk/catcher" "github.com/utmstack/utmstack/backend/modules/adaudit/connectors" "github.com/utmstack/utmstack/backend/modules/adaudit/dto" @@ -58,10 +59,11 @@ func (h *ADUserHandler) Ingest(c *gin.Context) { // @Param source query string false "Filter by source: windows | linux (omit for all)" // @Param active query bool false "Filter by active" // @Param status query string false "Lifecycle bucket: active|disabled|deleted|stale|service (overrides active)" +// @Param identity query string false "Filter by identity alias uuid, or the literal 'none' for users without one" // @Param sort query string false "Sort: recent (last seen) or name (default)" // @Param page query int false "Page (0-based)" // @Param size query int false "Page size" -// @Success 200 {array} domain.ADUser +// @Success 200 {array} dto.UserRow // @Header 200 {string} X-Total-Count "Total records" // @Failure 400 {object} map[string]string // @Failure 500 {object} map[string]string @@ -76,6 +78,12 @@ func (h *ADUserHandler) List(c *gin.Context) { c.JSON(http.StatusBadRequest, gin.H{"error": "source must be 'windows', 'linux', a cloud source, or omitted"}) return } + if f.Identity != "" && f.Identity != "none" { + if _, err := uuid.Parse(f.Identity); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "identity must be a uuid or the literal 'none'"}) + return + } + } res, err := h.uc.List(c.Request.Context(), f) if err != nil { _ = catcher.Error("adaudit: list failed", err, nil) diff --git a/backend/modules/adaudit/handler/identity_alias.go b/backend/modules/adaudit/handler/identity_alias.go new file mode 100644 index 000000000..71095c46f --- /dev/null +++ b/backend/modules/adaudit/handler/identity_alias.go @@ -0,0 +1,226 @@ +package handler + +import ( + "errors" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/google/uuid" + "github.com/threatwinds/go-sdk/catcher" + "github.com/utmstack/utmstack/backend/modules/adaudit/connectors" + "github.com/utmstack/utmstack/backend/modules/adaudit/dto" + "github.com/utmstack/utmstack/backend/modules/adaudit/repository" + "github.com/utmstack/utmstack/backend/modules/adaudit/usecase" + "github.com/utmstack/utmstack/backend/pkg/http/middleware" + "gorm.io/gorm" +) + +type IdentityHandler struct { + uc connectors.IdentityUsecase +} + +func NewIdentityHandler(uc connectors.IdentityUsecase) *IdentityHandler { + return &IdentityHandler{uc: uc} +} + +func actorIdentity(c *gin.Context) string { + if a := middleware.ActorFromGin(c); a != nil && a.Email != "" { + return a.Email + } + return "internal" +} + +var ErrIdentityAssignConflict = errors.New("user is already assigned to another identity") + +func writeIdentityError(c *gin.Context, op string, err error) { + switch { + case errors.Is(err, usecase.ErrIdentityNameInvalid): + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + case errors.Is(err, repository.ErrIdentityNotFound), + errors.Is(err, repository.ErrUserNotFound): + c.JSON(http.StatusNotFound, gin.H{"error": err.Error()}) + case errors.Is(err, repository.ErrIdentityNameTaken), + errors.Is(err, repository.ErrIdentityInUse), + errors.Is(err, ErrIdentityAssignConflict), + errors.Is(err, gorm.ErrDuplicatedKey): + c.JSON(http.StatusConflict, gin.H{"error": err.Error()}) + default: + _ = catcher.Error("adaudit: "+op+" failed", err, nil) + c.JSON(http.StatusInternalServerError, gin.H{"error": "could not " + op + " identity"}) + } +} + +// Create godoc +// +// @Summary Create an identity alias +// @Tags AD Audit +// @Security BearerAuth +// @Accept json +// @Produce json +// @Param input body dto.CreateIdentityRequest true "Alias name" +// @Success 200 {object} dto.IdentityResponse +// @Failure 400 {object} map[string]string +// @Failure 409 {object} map[string]string +// @Failure 500 {object} map[string]string +// @Router /ad-audit/identities [post] +func (h *IdentityHandler) Create(c *gin.Context) { + var req dto.CreateIdentityRequest + if err := c.ShouldBindJSON(&req); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } + res, err := h.uc.Create(c.Request.Context(), req.Name, actorIdentity(c)) + if err != nil { + writeIdentityError(c, "create", err) + return + } + c.JSON(http.StatusOK, res) +} + +// List godoc +// +// @Summary List identity aliases +// @Tags AD Audit +// @Security BearerAuth +// @Produce json +// @Param search query string false "Case-insensitive substring on name" +// @Success 200 {array} dto.IdentityListItem +// @Failure 500 {object} map[string]string +// @Router /ad-audit/identities [get] +func (h *IdentityHandler) List(c *gin.Context) { + items, err := h.uc.List(c.Request.Context(), c.Query("search")) + if err != nil { + _ = catcher.Error("adaudit: identity list failed", err, nil) + c.JSON(http.StatusInternalServerError, gin.H{"error": "could not list identities"}) + return + } + c.JSON(http.StatusOK, items) +} + +// Detail godoc +// +// @Summary Show an identity alias and its users +// @Tags AD Audit +// @Security BearerAuth +// @Produce json +// @Param id path string true "Identity id" +// @Success 200 {object} dto.IdentityDetail +// @Failure 404 {object} map[string]string +// @Failure 500 {object} map[string]string +// @Router /ad-audit/identities/{id} [get] +func (h *IdentityHandler) Detail(c *gin.Context) { + id, err := uuid.Parse(c.Param("id")) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "id is not a valid id"}) + return + } + res, err := h.uc.Detail(c.Request.Context(), id) + if err != nil { + writeIdentityError(c, "load", err) + return + } + c.JSON(http.StatusOK, res) +} + +// Delete godoc +// +// @Summary Delete an identity alias +// @Tags AD Audit +// @Security BearerAuth +// @Produce json +// @Param id path string true "Identity id" +// @Success 200 {object} map[string]int +// @Failure 404 {object} map[string]string +// @Failure 409 {object} map[string]string +// @Failure 500 {object} map[string]string +// @Router /ad-audit/identities/{id} [delete] +func (h *IdentityHandler) Delete(c *gin.Context) { + id, err := uuid.Parse(c.Param("id")) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "id is not a valid id"}) + return + } + n, err := h.uc.Delete(c.Request.Context(), id) + if err != nil { + writeIdentityError(c, "delete", err) + return + } + c.JSON(http.StatusOK, gin.H{"deleted": n}) +} + +// Assign godoc +// +// @Summary Assign a user to an identity alias +// @Description An empty or null identityId unassigns the user. +// @Tags AD Audit +// @Security BearerAuth +// @Accept json +// @Produce json +// @Param id path string true "User id" +// @Param input body dto.AssignIdentityRequest true "Identity to assign" +// @Success 200 {object} map[string]bool +// @Failure 400 {object} map[string]string +// @Failure 404 {object} map[string]string +// @Failure 409 {object} map[string]string +// @Failure 500 {object} map[string]string +// @Router /ad-audit/users/{id}/identity [put] +func (h *IdentityHandler) Assign(c *gin.Context) { + userID, err := uuid.Parse(c.Param("id")) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "id is not a valid id"}) + return + } + var req dto.AssignIdentityRequest + if c.Request.ContentLength > 0 { + if err := c.ShouldBindJSON(&req); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "body must be a JSON object with an 'identityId' string"}) + return + } + } + if req.IdentityID == "" { + if err := h.uc.Unassign(c.Request.Context(), userID, actorIdentity(c)); err != nil { + writeIdentityError(c, "assign", err) + return + } + c.JSON(http.StatusOK, gin.H{"assigned": false}) + return + } + aliasID, err := uuid.Parse(req.IdentityID) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "identityId is not a valid id"}) + return + } + if err := h.uc.Assign(c.Request.Context(), userID, aliasID, actorIdentity(c)); err != nil { + if errors.Is(err, gorm.ErrDuplicatedKey) { + c.JSON(http.StatusConflict, gin.H{"error": ErrIdentityAssignConflict.Error()}) + return + } + writeIdentityError(c, "assign", err) + return + } + c.JSON(http.StatusOK, gin.H{"assigned": true}) +} + +// Unassign godoc +// +// @Summary Remove a user from its identity alias +// @Tags AD Audit +// @Security BearerAuth +// @Produce json +// @Param id path string true "User id" +// @Success 200 {object} map[string]bool +// @Failure 404 {object} map[string]string +// @Failure 500 {object} map[string]string +// @Router /ad-audit/users/{id}/identity [patch] +func (h *IdentityHandler) Unassign(c *gin.Context) { + userID, err := uuid.Parse(c.Param("id")) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "id is not a valid id"}) + return + } + if err := h.uc.Unassign(c.Request.Context(), userID, actorIdentity(c)); err != nil { + writeIdentityError(c, "assign", err) + return + } + c.JSON(http.StatusOK, gin.H{"assigned": false}) +} diff --git a/backend/modules/adaudit/module.go b/backend/modules/adaudit/module.go index 1ef597e73..925062681 100644 --- a/backend/modules/adaudit/module.go +++ b/backend/modules/adaudit/module.go @@ -9,15 +9,24 @@ import ( ) type Module struct { - handler *handler.ADUserHandler - uc connectors.ADUserUsecase + handler *handler.ADUserHandler + identity *handler.IdentityHandler + uc connectors.ADUserUsecase } func NewModule(db *gorm.DB) *Module { - repo := repository.NewADUserRepository(db) - uc := usecase.NewADUserUsecase(repo) - return &Module{handler: handler.NewADUserHandler(uc), uc: uc} + adRepo := repository.NewADUserRepository(db) + identityRepo := repository.NewIdentityRepository(db) + uc := usecase.NewADUserUsecase(adRepo) + return &Module{ + handler: handler.NewADUserHandler(uc), + identity: handler.NewIdentityHandler(usecase.NewIdentityUsecase(identityRepo)), + uc: uc, + } } -func (m *Module) Handler() *handler.ADUserHandler { return m.handler } +func (m *Module) Handler() *handler.ADUserHandler { return m.handler } +func (m *Module) Identity() *handler.IdentityHandler { + return m.identity +} func (m *Module) GetUsecase() connectors.ADUserUsecase { return m.uc } diff --git a/backend/modules/adaudit/repository/ad_user_pg.go b/backend/modules/adaudit/repository/ad_user_pg.go index c2a1c332d..f61d16d11 100644 --- a/backend/modules/adaudit/repository/ad_user_pg.go +++ b/backend/modules/adaudit/repository/ad_user_pg.go @@ -4,6 +4,8 @@ import ( "context" "errors" + "github.com/google/uuid" + "github.com/utmstack/utmstack/backend/modules/adaudit/connectors" "github.com/utmstack/utmstack/backend/modules/adaudit/domain" "github.com/utmstack/utmstack/backend/modules/adaudit/dto" @@ -230,54 +232,74 @@ func (r *pgADUserRepository) ResolveLinuxIdentity(ctx context.Context, tenantID, } func applyStatus(q *gorm.DB, status string) *gorm.DB { + return applyStatusQualified(q, "ad_user", status) +} + +func applyStatusQualified(q *gorm.DB, table, status string) *gorm.DB { switch status { case "active": - return q.Where("active = true AND account_deleted_at IS NULL") + return q.Where(table + ".active = true AND " + table + ".account_deleted_at IS NULL") case "disabled": - return q.Where("active = false AND account_deleted_at IS NULL") + return q.Where(table + ".active = false AND " + table + ".account_deleted_at IS NULL") case "deleted": - return q.Where("account_deleted_at IS NOT NULL") + return q.Where(table + ".account_deleted_at IS NOT NULL") case "stale": - return q.Where("active = true AND account_deleted_at IS NULL AND last_logon IS NOT NULL AND last_logon < NOW() - INTERVAL '30 days'") + return q.Where(table + ".active = true AND " + table + ".account_deleted_at IS NULL AND " + table + ".last_logon IS NOT NULL AND " + table + ".last_logon < NOW() - INTERVAL '30 days'") case "service": - return q.Where("account_deleted_at IS NULL AND sam_account_name ILIKE 'svc%' AND source = 'windows'") + return q.Where(table + ".account_deleted_at IS NULL AND " + table + ".sam_account_name ILIKE 'svc%' AND " + table + ".source = 'windows'") } return q } -func (r *pgADUserRepository) List(ctx context.Context, f dto.ADUserFilter) ([]domain.ADUser, int64, error) { - q := r.db.WithContext(ctx).Model(&domain.ADUser{}) +func (r *pgADUserRepository) List(ctx context.Context, f dto.ADUserFilter) ([]dto.UserRow, int64, error) { + q := r.db.WithContext(ctx).Model(&domain.ADUser{}). + Select("ad_user.*", "identity_alias.name AS identity"). + Joins("LEFT JOIN identity_alias_assignment ON identity_alias_assignment.user_id = ad_user.id"). + Joins("LEFT JOIN identity_alias ON identity_alias.id = identity_alias_assignment.alias_id") if f.Source != "" { - q = q.Where("source = ?", f.Source) + q = q.Where("ad_user.source = ?", f.Source) } if f.Status != "" { - // Status is a richer, derived filter; when present it supersedes the raw - // `active` flag so the two can't contradict each other. - q = applyStatus(q, f.Status) + q = applyStatusQualified(q, "ad_user", f.Status) } else if f.Active != nil { - q = q.Where("active = ?", *f.Active) + q = q.Where("ad_user.active = ?", *f.Active) } if f.Search != "" { - like := "%" + f.Search + "%" - q = q.Where("sam_account_name ILIKE ? OR sid ILIKE ? OR username ILIKE ?", like, like, like) + like := "%" + escapeLike(f.Search) + "%" + q = q.Where("ad_user.sam_account_name ILIKE ? OR ad_user.sid ILIKE ? OR ad_user.username ILIKE ?", like, like, like) } + q = applyIdentityFilter(q, f.Identity) var total int64 if err := q.Count(&total).Error; err != nil { return nil, 0, err } - order := "sam_account_name ASC" + order := "ad_user.sam_account_name ASC NULLS LAST" if f.Sort == "recent" { - order = "last_seen DESC NULLS LAST" + order = "ad_user.last_seen DESC NULLS LAST" } - var items []domain.ADUser - if err := q.Order(order).Offset(f.Offset()).Limit(f.Limit()).Find(&items).Error; err != nil { + var items []dto.UserRow + if err := q.Order(order).Offset(f.Offset()).Limit(f.Limit()).Scan(&items).Error; err != nil { return nil, 0, err } return items, total, nil } +func applyIdentityFilter(q *gorm.DB, identity string) *gorm.DB { + if identity == "" { + return q + } + if identity == "none" { + return q.Where("NOT EXISTS (SELECT 1 FROM identity_alias_assignment x WHERE x.user_id = ad_user.id)") + } + id, err := uuid.Parse(identity) + if err != nil { + return q + } + return q.Where("EXISTS (SELECT 1 FROM identity_alias_assignment x WHERE x.user_id = ad_user.id AND x.alias_id = ?)", id) +} + func (r *pgADUserRepository) Stats(ctx context.Context) (*dto.ADUserStats, error) { base := func() *gorm.DB { return r.db.WithContext(ctx).Model(&domain.ADUser{}) @@ -305,6 +327,12 @@ func (r *pgADUserRepository) Stats(ctx context.Context) (*dto.ADUserStats, error if err := base().Where("last_seen IS NOT NULL AND last_seen > NOW() - INTERVAL '24 hours'").Count(&s.Seen24h).Error; err != nil { return nil, err } + if err := r.db.WithContext(ctx).Model(&domain.IdentityAlias{}).Count(&s.Identities).Error; err != nil { + return nil, err + } + if err := base().Where("NOT EXISTS (SELECT 1 FROM identity_alias_assignment x WHERE x.user_id = ad_user.id)").Count(&s.Unassigned).Error; err != nil { + return nil, err + } var srcRows []sourceRow if err := base().Select("source, COUNT(*) AS count").Group("source").Scan(&srcRows).Error; err != nil { diff --git a/backend/modules/adaudit/repository/ad_user_pg_test.go b/backend/modules/adaudit/repository/ad_user_pg_test.go index cd6b173fc..c1492f240 100644 --- a/backend/modules/adaudit/repository/ad_user_pg_test.go +++ b/backend/modules/adaudit/repository/ad_user_pg_test.go @@ -21,7 +21,10 @@ func TestSplitByIdentity(t *testing.T) { windows := domain.ADUser{Source: "windows", SID: str("S-1-5-21-1")} unlabelled := domain.ADUser{SID: str("S-1-5-21-2")} - win, linuxKeyed, byAccount := splitByIdentity([]domain.ADUser{keyed, machineWithoutUID, uidWithoutMachine, blankMachine, windows, unlabelled}) + win, linuxKeyed, byAccount, cloud := splitByIdentity([]domain.ADUser{keyed, machineWithoutUID, uidWithoutMachine, blankMachine, windows, unlabelled}) + if len(cloud) != 0 { + t.Fatalf("no cloud account was supplied, got %+v", cloud) + } if len(linuxKeyed) != 1 || linuxKeyed[0].UIDNumber == nil || *linuxKeyed[0].UIDNumber != 1000 || *linuxKeyed[0].MachineID != "m-1" { t.Fatalf("only the account with machine and uid is keyed, got %+v", linuxKeyed) diff --git a/backend/modules/adaudit/repository/identity_alias_pg.go b/backend/modules/adaudit/repository/identity_alias_pg.go new file mode 100644 index 000000000..65edd1494 --- /dev/null +++ b/backend/modules/adaudit/repository/identity_alias_pg.go @@ -0,0 +1,182 @@ +package repository + +import ( + "context" + "errors" + "strings" + + "github.com/google/uuid" + "github.com/utmstack/utmstack/backend/modules/adaudit/domain" + "github.com/utmstack/utmstack/backend/modules/adaudit/dto" + "gorm.io/gorm" + "gorm.io/gorm/clause" +) + +type identityRow struct { + domain.IdentityAlias + Count int +} + +var ( + ErrIdentityNameTaken = errors.New("an identity with this name already exists") + ErrIdentityNotFound = errors.New("identity not found") + ErrIdentityInUse = errors.New("identity still has assigned users") + ErrUserNotFound = errors.New("user not found") +) + +// escapeLike neutralizes % and _ in user input so it cannot be used to +// pattern-enumerate names in ILIKE filters. +func escapeLike(s string) string { + s = strings.NewReplacer(`\`, `\\`, `%`, `\%`, `_`, `\_`).Replace(s) + return s +} + +type pgIdentityRepository struct{ db *gorm.DB } + +func NewIdentityRepository(db *gorm.DB) *pgIdentityRepository { + return &pgIdentityRepository{db: db} +} + +func (r *pgIdentityRepository) Create(ctx context.Context, name, actor string) (*domain.IdentityAlias, error) { + alias := domain.IdentityAlias{Name: name, CreatedBy: actor} + if err := r.db.WithContext(ctx).Create(&alias).Error; err != nil { + if errors.Is(err, gorm.ErrDuplicatedKey) { + return nil, ErrIdentityNameTaken + } + return nil, err + } + return &alias, nil +} + +func (r *pgIdentityRepository) List(ctx context.Context, search string) ([]dto.IdentityListItem, error) { + q := r.db.WithContext(ctx).Model(&domain.IdentityAlias{}). + Select("identity_alias.id, identity_alias.name, identity_alias.created_at, COUNT(identity_alias_assignment.alias_id) AS count"). + Joins("LEFT JOIN identity_alias_assignment ON identity_alias_assignment.alias_id = identity_alias.id") + if search != "" { + q = q.Where("identity_alias.name ILIKE ?", "%"+escapeLike(search)+"%") + } + + var rows []identityRow + if err := q.Group("identity_alias.id").Order("identity_alias.name ASC").Scan(&rows).Error; err != nil { + return nil, err + } + items := make([]dto.IdentityListItem, 0, len(rows)) + for _, row := range rows { + items = append(items, dto.IdentityListItem{ + ID: row.ID.String(), + Name: row.Name, + CreatedAt: row.CreatedAt, + Count: row.Count, + }) + } + return items, nil +} + +func (r *pgIdentityRepository) Get(ctx context.Context, id uuid.UUID) (*domain.IdentityAlias, error) { + var alias domain.IdentityAlias + if err := r.db.WithContext(ctx).First(&alias, "id = ?", id).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, ErrIdentityNotFound + } + return nil, err + } + return &alias, nil +} + +func (r *pgIdentityRepository) Users(ctx context.Context, id uuid.UUID) ([]dto.UserRow, error) { + alias, err := r.Get(ctx, id) + if err != nil { + return nil, err + } + name := alias.Name + var rows []dto.UserRow + err = r.db.WithContext(ctx).Model(&domain.ADUser{}). + Joins("JOIN identity_alias_assignment ON identity_alias_assignment.user_id = ad_user.id"). + Where("identity_alias_assignment.alias_id = ?", id). + Order("ad_user.sam_account_name ASC NULLS LAST"). + Scan(&rows).Error + for i := range rows { + rows[i].Identity = &name + } + return rows, err +} + +func (r *pgIdentityRepository) Delete(ctx context.Context, id uuid.UUID) (int, error) { + if _, err := r.Get(ctx, id); err != nil { + return 0, err + } + + var deleted int64 + if err := r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error { + // Count under a row lock: a concurrent Assign's insert blocks on it and + // then fails the FK after the alias is gone, so the in-use check is atomic. + var assigned int64 + if err := tx.Clauses(clause.Locking{Strength: "UPDATE"}). + Model(&domain.IdentityAliasAssignment{}). + Where("alias_id = ?", id).Count(&assigned).Error; err != nil { + return err + } + if assigned > 0 { + return ErrIdentityInUse + } + + res := tx.Model(&domain.IdentityAliasAssignment{}).Where("alias_id = ?", id).Delete(&domain.IdentityAliasAssignment{}) + if res.Error != nil { + return res.Error + } + res = tx.Delete(&domain.IdentityAlias{}, "id = ?", id) + if res.Error != nil { + return res.Error + } + deleted = res.RowsAffected + return nil + }); err != nil { + return 0, err + } + return int(deleted), nil +} + +func (r *pgIdentityRepository) Assign(ctx context.Context, userID, aliasID uuid.UUID, actor string) error { + var user domain.ADUser + if err := r.db.WithContext(ctx).First(&user, "id = ?", userID).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return ErrUserNotFound + } + return err + } + + var alias domain.IdentityAlias + if err := r.db.WithContext(ctx).First(&alias, "id = ?", aliasID).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return ErrIdentityNotFound + } + return err + } + + return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error { + res := tx.Model(&domain.IdentityAliasAssignment{}).Where("user_id = ?", userID).Delete(&domain.IdentityAliasAssignment{}) + if res.Error != nil { + return res.Error + } + assignment := domain.IdentityAliasAssignment{ + AliasID: aliasID, + UserID: userID, + AssignedBy: actor, + } + return tx.Create(&assignment).Error + }) +} + +func (r *pgIdentityRepository) Unassign(ctx context.Context, userID uuid.UUID, actor string) error { + var user domain.ADUser + if err := r.db.WithContext(ctx).First(&user, "id = ?", userID).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return ErrUserNotFound + } + return err + } + res := r.db.WithContext(ctx).Model(&domain.IdentityAliasAssignment{}). + Where("user_id = ?", userID). + Delete(&domain.IdentityAliasAssignment{}) + return res.Error +} diff --git a/backend/modules/adaudit/routes.go b/backend/modules/adaudit/routes.go index fcf710ad6..415a4c1f4 100644 --- a/backend/modules/adaudit/routes.go +++ b/backend/modules/adaudit/routes.go @@ -15,4 +15,11 @@ func RegisterRoutes(api *gin.RouterGroup, m *Module, userAuth gin.HandlerFunc) { g.GET("/users", middleware.RequirePermission("adaudit.read"), h.List) g.GET("/stats", middleware.RequirePermission("adaudit.read"), h.Stats) + + g.POST("/identities", middleware.RequirePermission("adaudit.write"), m.Identity().Create) + g.GET("/identities", middleware.RequirePermission("adaudit.read"), m.Identity().List) + g.GET("/identities/:id", middleware.RequirePermission("adaudit.read"), m.Identity().Detail) + g.DELETE("/identities/:id", middleware.RequirePermission("adaudit.write"), m.Identity().Delete) + g.PUT("/users/:id/identity", middleware.RequirePermission("adaudit.write"), m.Identity().Assign) + g.PATCH("/users/:id/identity", middleware.RequirePermission("adaudit.write"), m.Identity().Unassign) } diff --git a/backend/modules/adaudit/usecase/ad_user.go b/backend/modules/adaudit/usecase/ad_user.go index c84223f23..33a319aad 100644 --- a/backend/modules/adaudit/usecase/ad_user.go +++ b/backend/modules/adaudit/usecase/ad_user.go @@ -115,12 +115,12 @@ func (u *adUserUsecase) Ingest(ctx context.Context, req dto.IngestRequest) (int, return len(users), nil } -func (u *adUserUsecase) List(ctx context.Context, f dto.ADUserFilter) (*database.List[domain.ADUser], error) { +func (u *adUserUsecase) List(ctx context.Context, f dto.ADUserFilter) (*database.List[dto.UserRow], error) { items, total, err := u.repo.List(ctx, f) if err != nil { return nil, err } - return &database.List[domain.ADUser]{Items: items, Total: total}, nil + return &database.List[dto.UserRow]{Items: items, Total: total}, nil } func (u *adUserUsecase) Each(ctx context.Context, source string, fn func(domain.ADUser) error) error { diff --git a/backend/modules/adaudit/usecase/identity_alias.go b/backend/modules/adaudit/usecase/identity_alias.go new file mode 100644 index 000000000..cd970e124 --- /dev/null +++ b/backend/modules/adaudit/usecase/identity_alias.go @@ -0,0 +1,74 @@ +package usecase + +import ( + "context" + "errors" + "strings" + + "github.com/google/uuid" + + "github.com/utmstack/utmstack/backend/modules/adaudit/connectors" + "github.com/utmstack/utmstack/backend/modules/adaudit/domain" + "github.com/utmstack/utmstack/backend/modules/adaudit/dto" + "github.com/utmstack/utmstack/backend/modules/adaudit/repository" +) + +var ( + ErrIdentityNameInvalid = errors.New("name must be 2 to 64 characters") +) + +type identityUsecase struct { + repo connectors.IdentityRepository +} + +func NewIdentityUsecase(repo connectors.IdentityRepository) connectors.IdentityUsecase { + return &identityUsecase{repo: repo} +} + +func (u *identityUsecase) Create(ctx context.Context, name, actor string) (*dto.IdentityResponse, error) { + name = strings.TrimSpace(name) + if !domain.ValidIdentityName(name) { + return nil, ErrIdentityNameInvalid + } + alias, err := u.repo.Create(ctx, name, actor) + if err != nil { + if errors.Is(err, repository.ErrIdentityNameTaken) { + return nil, err + } + return nil, err + } + return &dto.IdentityResponse{ID: alias.ID.String(), Name: alias.Name, CreatedAt: alias.CreatedAt}, nil +} + +func (u *identityUsecase) List(ctx context.Context, search string) ([]dto.IdentityListItem, error) { + return u.repo.List(ctx, search) +} + +func (u *identityUsecase) Detail(ctx context.Context, id uuid.UUID) (*dto.IdentityDetail, error) { + alias, err := u.repo.Get(ctx, id) + if err != nil { + return nil, err + } + users, err := u.repo.Users(ctx, id) + if err != nil { + return nil, err + } + return &dto.IdentityDetail{ + ID: alias.ID.String(), + Name: alias.Name, + CreatedAt: alias.CreatedAt, + Users: users, + }, nil +} + +func (u *identityUsecase) Delete(ctx context.Context, id uuid.UUID) (int, error) { + return u.repo.Delete(ctx, id) +} + +func (u *identityUsecase) Assign(ctx context.Context, userID, aliasID uuid.UUID, actor string) error { + return u.repo.Assign(ctx, userID, aliasID, actor) +} + +func (u *identityUsecase) Unassign(ctx context.Context, userID uuid.UUID, actor string) error { + return u.repo.Unassign(ctx, userID, actor) +} diff --git a/frontend/src/features/user-auditor/components/identity-group-picker.tsx b/frontend/src/features/user-auditor/components/identity-group-picker.tsx new file mode 100644 index 000000000..123a8da28 --- /dev/null +++ b/frontend/src/features/user-auditor/components/identity-group-picker.tsx @@ -0,0 +1,174 @@ +import { useEffect, useRef, useState } from 'react' +import { Check, ChevronDown, Loader2, Plus, UserCircle2, X } from 'lucide-react' +import { useTranslation } from 'react-i18next' +import { toast } from 'sonner' +import { adAuditHttpService } from '../services/ad-audit-http.service' +import type { IdentityListItem } from '../types/ad-user.types' + +/** + * Dropdown to assign a user to an existing identity group or create a new one. + * Mirrors IncidentAssigneePicker from the incidents drawer, backed by /ad-audit/identities. + */ +export function IdentityGroupPicker({ + userId, + current, + onChanged, +}: { + userId: string + current: string | null + onChanged: (name: string | null) => void +}) { + const { t } = useTranslation() + const [open, setOpen] = useState(false) + const [q, setQ] = useState('') + const [custom, setCustom] = useState('') + const [items, setItems] = useState(null) + const [busy, setBusy] = useState(false) + const ref = useRef(null) + + // Load the alias list on open; search below filters client-side. + useEffect(() => { + if (!open) return + let cancelled = false + void adAuditHttpService + .identities() + .then((res) => { + if (!cancelled) setItems(res ?? []) + }) + .catch(() => { + if (!cancelled) setItems([]) + }) + return () => { + cancelled = true + } + }, [open]) + + useEffect(() => { + if (!open) return + const onDoc = (e: MouseEvent) => ref.current && !ref.current.contains(e.target as Node) && setOpen(false) + document.addEventListener('mousedown', onDoc) + return () => document.removeEventListener('mousedown', onDoc) + }, [open]) + + const assign = (id: string) => { + setBusy(true) + void adAuditHttpService + .assignIdentity(userId, id) + .then(() => { + const name = id ? items?.find((i) => i.id === id)?.name ?? null : null + setOpen(false) + setCustom('') + onChanged(name) + toast.success(t('userAuditor.drawer.alias.updated')) + }) + .catch(() => toast.error(t('userAuditor.drawer.alias.updateFailed'))) + .finally(() => setBusy(false)) + } + + const createAndAssign = () => { + const name = custom.trim() + if (name.length < 2) { + toast.error(t('userAuditor.drawer.alias.nameTooShort')) + return + } + setBusy(true) + void adAuditHttpService + .createIdentity(name) + .then((res) => { + if (!res) throw new Error('no identity') + return adAuditHttpService.assignIdentity(userId, res.id) + }) + .then(() => { + setOpen(false) + setCustom('') + onChanged(name) + toast.success(t('userAuditor.drawer.alias.updated')) + }) + .catch(() => toast.error(t('userAuditor.drawer.alias.updateFailed'))) + .finally(() => setBusy(false)) + } + + const customTrimmed = custom.trim() + const canCreateCustom = customTrimmed.length >= 2 && customTrimmed !== current + const filtered = (items ?? []).filter((i) => (q ? i.name.toLowerCase().includes(q.toLowerCase()) : true)) + + return ( +
+ + {open && ( +
+
+ setQ(e.target.value)} + autoFocus + placeholder={t('userAuditor.drawer.alias.search')} + className="h-7 w-full rounded-md border border-input bg-background px-2 text-xs focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring" + /> +
+ {current && ( + + )} +
+ {items === null && ( +
+ +
+ )} + {items !== null && filtered.length === 0 && ( +
{t('userAuditor.drawer.alias.none')}
+ )} + {filtered.map((i) => ( + + ))} +
+
+
+ {t('userAuditor.drawer.alias.new')} +
+
+ setCustom(e.target.value)} + onKeyDown={(e) => e.key === 'Enter' && createAndAssign()} + placeholder={t('userAuditor.drawer.alias.newPlaceholder')} + className="h-7 min-w-0 flex-1 rounded-md border border-input bg-background px-2 text-xs focus-visible:border-ring focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring" + /> + +
+
+
+ )} +
+ ) +} diff --git a/frontend/src/features/user-auditor/components/overview-card.tsx b/frontend/src/features/user-auditor/components/overview-card.tsx index 18258863c..924f8cb05 100644 --- a/frontend/src/features/user-auditor/components/overview-card.tsx +++ b/frontend/src/features/user-auditor/components/overview-card.tsx @@ -1,5 +1,5 @@ import type { TFunction } from 'i18next' -import { Clock } from 'lucide-react' +import { Clock, UserMinus, Users } from 'lucide-react' import type { ADUserStats } from '../types/ad-user.types' export function OverviewCard({ stats, t }: { stats: ADUserStats | null; t: TFunction }) { @@ -24,9 +24,19 @@ export function OverviewCard({ stats, t }: { stats: ADUserStats | null; t: TFunc {t('userAuditor.overview.deleted')} -
- - {t('userAuditor.overview.seen24h', { count: stats?.seen_24h ?? 0 })} +
+ + + {t('userAuditor.overview.seen24h', { count: stats?.seen_24h ?? 0 })} + + + + {t('userAuditor.overview.grouped', { count: stats?.identities ?? 0 })} + + + + {t('userAuditor.overview.unassigned', { count: stats?.unassigned ?? 0 })} +
diff --git a/frontend/src/features/user-auditor/components/toolbar.tsx b/frontend/src/features/user-auditor/components/toolbar.tsx index f740afbc4..1f23ca91c 100644 --- a/frontend/src/features/user-auditor/components/toolbar.tsx +++ b/frontend/src/features/user-auditor/components/toolbar.tsx @@ -1,5 +1,5 @@ import type { TFunction } from 'i18next' -import { ChevronDown, LayoutGrid, ListIcon, RefreshCw, Search, Server } from 'lucide-react' +import { ChevronDown, LayoutGrid, ListIcon, RefreshCw, Search, Server, Users } from 'lucide-react' import { cn } from '@/shared/lib/utils' import { Input } from '@/shared/components/ui/input' @@ -9,6 +9,9 @@ export function Toolbar({ tenant, tenants, onTenant, + identity, + identities, + onIdentity, layout, onLayoutChange, onRefresh, @@ -20,6 +23,9 @@ export function Toolbar({ tenant: string tenants: string[] onTenant: (t: string) => void + identity: string + identities: { id: string; name: string }[] + onIdentity: (id: string) => void layout: 'list' | 'cards' onLayoutChange: (l: 'list' | 'cards') => void onRefresh: () => void @@ -55,6 +61,23 @@ export function Toolbar({ )} +
+ + + +
{accountScope(user)}
+ {user.identity && ( +
+ + {user.identity} + +
+ )}
diff --git a/frontend/src/features/user-auditor/components/user-drawer.tsx b/frontend/src/features/user-auditor/components/user-drawer.tsx index 47485ce0d..4f7568f3b 100644 --- a/frontend/src/features/user-auditor/components/user-drawer.tsx +++ b/frontend/src/features/user-auditor/components/user-drawer.tsx @@ -1,14 +1,15 @@ import { Link } from 'react-router-dom' import type { TFunction } from 'i18next' -import { Copy, ExternalLink, Server, X } from 'lucide-react' +import { Copy, ExternalLink, Server, UserCircle2, X } from 'lucide-react' import { toast } from 'sonner' import { cn } from '@/shared/lib/utils' import { Button } from '@/shared/components/ui/button' -import type { ADUser } from '../types/ad-user.types' +import type { ADUserWithIdentity } from '../types/ad-user.types' import { accountIdentity, accountName, accountScope, + isCloudSource, isService, isStale, logExplorerHref, @@ -17,17 +18,38 @@ import { statusOf, } from '../helpers/user-auditor-display' import { AccountAvatar } from './account-avatar' +import { IdentityGroupPicker } from './identity-group-picker' import { Row, Section } from './section-row' import { Timeline } from './timeline' -export function UserDrawer({ user, onClose, t }: { user: ADUser; onClose: () => void; t: TFunction }) { +export function UserDrawer({ + user, + canManage, + onClose, + onUserChanged, + t, +}: { + user: ADUserWithIdentity + canManage: boolean + onClose: () => void + onUserChanged: (u: ADUserWithIdentity) => void + t: TFunction +}) { const status = statusOf(user) const identity = accountIdentity(user) + const isCloud = isCloudSource(user.source) + const isLinux = user.source === 'linux' + const logsHref = logExplorerHref(user) + const copyId = () => { void navigator.clipboard?.writeText(identity) toast.success(t('userAuditor.drawer.copied')) } - const isLinux = user.source === 'linux' + + const onAliasChanged = (name: string | null) => { + onUserChanged({ ...user, identity: name }) + } + return (
- + {logsHref && ( + + )} + {canManage} + {canManage && ( + + )}
@@ -95,11 +123,11 @@ export function UserDrawer({ user, onClose, t }: { user: ADUser; onClose: () => {accountName(user)} - - {accountScope(user)} - - {isLinux ? ( + {isLinux && ( <> + + {accountScope(user)} + {user.uidNumber ?? '—'} @@ -107,10 +135,16 @@ export function UserDrawer({ user, onClose, t }: { user: ADUser; onClose: () => {user.machineId ?? '—'} - ) : ( - - {user.sid ?? '—'} - + )} + {user.source === 'windows' && ( + <> + + {accountScope(user)} + + + {user.sid ?? '—'} + + )} {user.tenantId} @@ -118,6 +152,16 @@ export function UserDrawer({ user, onClose, t }: { user: ADUser; onClose: () => {user.active ? t('userAuditor.drawer.enabled') : t('userAuditor.drawer.disabled')} + + {user.identity ? ( + + + {user.identity} + + ) : ( + {t('userAuditor.drawer.alias.unassigned')} + )} + diff --git a/frontend/src/features/user-auditor/helpers/user-auditor-columns.tsx b/frontend/src/features/user-auditor/helpers/user-auditor-columns.tsx index 849a2cf7f..a301d98d0 100644 --- a/frontend/src/features/user-auditor/helpers/user-auditor-columns.tsx +++ b/frontend/src/features/user-auditor/helpers/user-auditor-columns.tsx @@ -2,7 +2,7 @@ import type { TFunction } from 'i18next' import type { ColumnDef } from '@tanstack/react-table' import { ExternalLink } from 'lucide-react' import { cn } from '@/shared/lib/utils' -import type { ADUser } from '../types/ad-user.types' +import type { ADUserWithIdentity } from '../types/ad-user.types' import { accountIdentity, accountName, @@ -19,7 +19,7 @@ import { AccountAvatar } from '../components/account-avatar' export const TH = 'whitespace-nowrap px-3 py-2 text-left align-middle font-medium' const TD = 'whitespace-nowrap px-3 py-2.5 align-middle' -export function buildUserColumns(t: TFunction): ColumnDef[] { +export function buildUserColumns(t: TFunction): ColumnDef[] { const muted = `${TD} font-mono text-[11px] text-muted-foreground` return [ { @@ -64,7 +64,7 @@ export function buildUserColumns(t: TFunction): ColumnDef[] { }, { id: 'identity', - header: t('userAuditor.list.identity'), + header: t('userAuditor.list.accountId'), size: 260, minSize: 80, meta: { @@ -74,6 +74,22 @@ export function buildUserColumns(t: TFunction): ColumnDef[] { }, cell: ({ row }) => {accountIdentity(row.original)}, }, + { + id: 'identityGroup', + header: t('userAuditor.list.identityGroup'), + size: 180, + minSize: 100, + meta: { headerClassName: TH, cellClassName: TD }, + cell: ({ row }) => { + const group = (row.original as ADUserWithIdentity).identity + if (!group) return — + return ( + + {group} + + ) + }, + }, { id: 'status', header: t('userAuditor.list.status'), diff --git a/frontend/src/features/user-auditor/helpers/user-auditor-display.ts b/frontend/src/features/user-auditor/helpers/user-auditor-display.ts index c7e0d4daf..9e7f96826 100644 --- a/frontend/src/features/user-auditor/helpers/user-auditor-display.ts +++ b/frontend/src/features/user-auditor/helpers/user-auditor-display.ts @@ -1,10 +1,15 @@ import type { TFunction } from 'i18next' +import { CLOUD_SOURCES } from '../types/ad-user.types' import type { ADUser } from '../types/ad-user.types' export const STALE_MS = 30 * 86_400_000 export type ViewId = 'all' | ADUser['source'] -export const VIEW_IDS: ViewId[] = ['all', 'windows', 'linux'] +export const VIEW_IDS: ViewId[] = ['all', 'windows', 'linux', ...CLOUD_SOURCES] + +export function isCloudSource(source: ADUser['source']): boolean { + return (CLOUD_SOURCES as string[]).includes(source) +} export type Status = 'active' | 'disabled' | 'deleted' @@ -31,9 +36,10 @@ export function isService(u: ADUser): boolean { return u.source === 'windows' && /^svc/i.test(u.samAccountName ?? '') } -/* Windows accounts key off SID + samAccountName; Linux accounts off username + uid@host. */ +/* Windows accounts key off SID + samAccountName; Linux accounts off username + uid@host; cloud accounts off username only. */ export function accountName(u: ADUser): string { - return (u.source === 'linux' ? u.username : u.samAccountName) ?? '—' + if (u.source === 'linux' || isCloudSource(u.source)) return u.username ?? '—' + return u.samAccountName ?? '—' } export function accountIdentity(u: ADUser): string { if (u.source === 'linux') { @@ -41,9 +47,11 @@ export function accountIdentity(u: ADUser): string { const host = u.hostname ?? '' return [uid, host].filter(Boolean).join(' · ') || '—' } + if (isCloudSource(u.source)) return u.username ?? '—' return u.sid ?? '—' } export function accountScope(u: ADUser): string { + if (isCloudSource(u.source)) return '—' return (u.source === 'linux' ? u.hostname : u.domain) ?? '—' } @@ -68,7 +76,8 @@ export function absTimestamp(iso: string) { }) } -export function logExplorerHref(user: ADUser): string { +export function logExplorerHref(user: ADUser): string | null { + if (isCloudSource(user.source)) return null // no dataType filter for cloud sources yet const p: Record = { tenantId: user.tenantId, '@timestamp': '30d' } if (user.source === 'linux') { p.dataType = 'linux' diff --git a/frontend/src/features/user-auditor/pages/UserAuditorPage.tsx b/frontend/src/features/user-auditor/pages/UserAuditorPage.tsx index 6deed54de..4a19fd3ab 100644 --- a/frontend/src/features/user-auditor/pages/UserAuditorPage.tsx +++ b/frontend/src/features/user-auditor/pages/UserAuditorPage.tsx @@ -10,8 +10,13 @@ import type { FilterFieldDef, FilterOpDef, } from '@/shared/components/filters/custom-filter.types' +import { useAuth } from '@/features/auth/services/auth.context' import { adAuditHttpService } from '../services/ad-audit-http.service' -import type { ADUser, ADUserStats, ADUserStatus } from '../types/ad-user.types' +import type { + ADUserStats, + ADUserStatus, + ADUserWithIdentity, +} from '../types/ad-user.types' import { type ViewId } from '../helpers/user-auditor-display' import { buildUserColumns } from '../helpers/user-auditor-columns' import { UserAuditorHeader } from '../components/user-auditor-header' @@ -35,20 +40,24 @@ function LoadingRows() { export function UserAuditorPage() { const { t } = useTranslation() + const { hasPermission } = useAuth() + const canManage = hasPermission('adaudit.write') const [view, setView] = useState('all') const [searchInput, setSearchInput] = useState('') const [search, setSearch] = useState('') const [tenant, setTenant] = useState('') // '' = all + const [identity, setIdentity] = useState('') // '' = all, 'none' = unassigned, else alias uuid const [layout, setLayout] = useState<'list' | 'cards'>('list') const [page, setPage] = useState(0) const [customFilters, setCustomFilters] = useState([]) - const [users, setUsers] = useState([]) + const [users, setUsers] = useState([]) const [total, setTotal] = useState(0) const [loading, setLoading] = useState(true) const [error, setError] = useState(false) const [stats, setStats] = useState(null) - const [openUser, setOpenUser] = useState(null) + const [identities, setIdentities] = useState<{ id: string; name: string }[]>([]) + const [openUser, setOpenUser] = useState(null) const filterFields: FilterFieldDef[] = [ { field: 'status', label: t('userAuditor.filterFields.status') }, @@ -79,7 +88,7 @@ export function UserAuditorPage() { // Any filter change resets to the first page. useEffect(() => { setPage(0) - }, [view, search, tenant, customFilters]) + }, [view, search, tenant, identity, customFilters]) const loadStats = useCallback(async () => { try { @@ -89,6 +98,15 @@ export function UserAuditorPage() { } }, [tenant]) + // Identity aliases are best-effort too: the list works without them. + const loadIdentities = useCallback(async () => { + try { + setIdentities(await adAuditHttpService.identities() ?? []) + } catch { + setIdentities([]) + } + }, []) + const load = useCallback(async () => { setLoading(true) setError(false) @@ -100,6 +118,7 @@ export function UserAuditorPage() { source: view === 'all' ? undefined : view, status: statusFilter ? (statusFilter as ADUserStatus) : undefined, sort: 'recent', + identity: identity || undefined, page, size: SIZE, }) @@ -112,25 +131,41 @@ export function UserAuditorPage() { } finally { setLoading(false) } - }, [search, tenant, view, page, customFilters]) + }, [search, tenant, identity, view, page, customFilters]) useEffect(() => { void load() }, [load]) + useEffect(() => { void loadStats() }, [loadStats]) + useEffect(() => { + void loadIdentities() + }, [loadIdentities]) + const refresh = () => { if (page === 0) void load() else setPage(0) void loadStats() + void loadIdentities() + } + + const onUserChanged = (u: ADUserWithIdentity) => { + setOpenUser(u) + loadIdentities() + setUsers((prev) => prev.map((x) => (x.id === u.id ? u : x))) } const counts: Record = { all: stats?.total ?? 0, windows: stats?.by_source?.windows ?? 0, linux: stats?.by_source?.linux ?? 0, + o365: stats?.by_source?.o365 ?? 0, + azure: stats?.by_source?.azure ?? 0, + gcp: stats?.by_source?.gcp ?? 0, + aws: stats?.by_source?.aws ?? 0, } return ( @@ -151,6 +186,9 @@ export function UserAuditorPage() { tenant={tenant} tenants={stats?.tenants ?? []} onTenant={setTenant} + identity={identity} + identities={identities} + onIdentity={setIdentity} layout={layout} onLayoutChange={setLayout} onRefresh={refresh} @@ -225,7 +263,15 @@ export function UserAuditorPage() { /> )} - {openUser && setOpenUser(null)} t={t} />} + {openUser && ( + setOpenUser(null)} + onUserChanged={onUserChanged} + t={t} + /> + )}
) } diff --git a/frontend/src/features/user-auditor/services/ad-audit-http.service.ts b/frontend/src/features/user-auditor/services/ad-audit-http.service.ts index cc976a5c3..de113fb7d 100644 --- a/frontend/src/features/user-auditor/services/ad-audit-http.service.ts +++ b/frontend/src/features/user-auditor/services/ad-audit-http.service.ts @@ -1,5 +1,5 @@ import { ApiError, createApiClient } from '@/shared/lib/api-client' -import type { ADUser, ADUserListQuery, ADUserStats } from '../types/ad-user.types' +import type { ADUserWithIdentity, ADUserListQuery, ADUserStats, Identity, IdentityDetail, IdentityListItem } from '../types/ad-user.types' const api = createApiClient() @@ -12,14 +12,25 @@ function listQuery(q: ADUserListQuery): string { if (q.source) p.set('source', q.source) if (q.status) p.set('status', q.status) if (q.sort) p.set('sort', q.sort) + if (q.identity) p.set('identity', q.identity) p.set('page', String(q.page ?? 0)) p.set('size', String(q.size ?? 25)) return `?${p.toString()}` } export const adAuditHttpService = { - // Returns { data: ADUser[], total } — total comes from the X-Total-Count header. - list: (q: ADUserListQuery = {}) => api.getPaged(`/ad-audit/users${listQuery(q)}`), + // Returns { data: ADUserWithIdentity[], total } — total comes from the X-Total-Count header. + list: (q: ADUserListQuery = {}) => api.getPaged(`/ad-audit/users${listQuery(q)}`), stats: (tenantId?: string) => api.get(`/ad-audit/stats${tenantId ? `?tenantId=${encodeURIComponent(tenantId)}` : ''}`), + + // Identity aliases. + identities: (search?: string) => + api.get(`/ad-audit/identities${search ? `?search=${encodeURIComponent(search)}` : ''}`), + identityDetail: (id: string) => api.get(`/ad-audit/identities/${id}`), + createIdentity: (name: string) => api.post(`/ad-audit/identities`, { name }), + deleteIdentity: (id: string) => api.delete<{ deleted: number }>(`/ad-audit/identities/${id}`), + // Empty identityId unassigns the user (backend semantics). + assignIdentity: (userId: string, identityId: string) => + api.put<{ assigned: boolean }>(`/ad-audit/users/${userId}/identity`, { identityId }), } diff --git a/frontend/src/features/user-auditor/types/ad-user.types.ts b/frontend/src/features/user-auditor/types/ad-user.types.ts index 8ecb12aa0..c216de332 100644 --- a/frontend/src/features/user-auditor/types/ad-user.types.ts +++ b/frontend/src/features/user-auditor/types/ad-user.types.ts @@ -1,8 +1,11 @@ /* Types mirror the backend adaudit DTOs (modules/adaudit/dto, domain.ADUser). */ -export type ADUserSource = 'windows' | 'linux' +/* Cloud: windows | linux | o365 | azure | gcp | aws */ +export type ADUserSource = 'windows' | 'linux' | 'o365' | 'azure' | 'gcp' | 'aws' -/** One user account observed in ingested Windows or Linux logs. */ +export const CLOUD_SOURCES: ADUserSource[] = ['o365', 'azure', 'gcp', 'aws'] + +/** One user account observed in ingested Windows, Linux or cloud logs. */ export interface ADUser { id: string tenantId: string @@ -16,6 +19,7 @@ export interface ADUser { uidNumber?: number hostname?: string username?: string + /* Cloud-only fields */ /* Shared lifecycle */ active: boolean accountCreatedAt?: string @@ -35,10 +39,31 @@ export interface ADUserListQuery { source?: ADUserSource status?: ADUserStatus sort?: ADUserSort + identity?: string // alias uuid, or the literal 'none' page?: number // zero-based size?: number } +/** Row returned by GET /ad-audit/users: the account plus its assigned identity alias name (null when unassigned). */ +export type ADUserWithIdentity = ADUser & { identity?: string | null } + +/** GET /ad-audit/identities — an operator-named identity alias. */ +export interface Identity { + id: string + name: string + createdAt: string +} + +/** GET /ad-audit/identities list item: the alias plus how many accounts it covers. */ +export interface IdentityListItem extends Identity { + count: number +} + +/** GET /ad-audit/identities/:id — the alias and every account assigned to it. */ +export interface IdentityDetail extends Identity { + users: ADUserWithIdentity[] +} + export interface DomainCount { domain: string count: number @@ -47,6 +72,10 @@ export interface DomainCount { export interface SourceCount { windows: number linux: number + o365: number + azure: number + gcp: number + aws: number } /** GET /ad-audit/stats — inventory roll-up for the overview. */ @@ -58,6 +87,8 @@ export interface ADUserStats { stale: number service: number seen_24h: number + identities: number + unassigned: number by_source: SourceCount by_domain: DomainCount[] tenants: string[] diff --git a/frontend/src/shared/i18n/locales/de.json b/frontend/src/shared/i18n/locales/de.json index 4892a70a9..e04d5feec 100644 --- a/frontend/src/shared/i18n/locales/de.json +++ b/frontend/src/shared/i18n/locales/de.json @@ -1278,7 +1278,9 @@ "disabled": "deaktiviert", "deleted": "gelöscht", "seen24h": "{{count}} in den letzten 24 Stunden gesehen", - "byDomain": "Nach Domäne" + "byDomain": "Nach Domäne", + "grouped": "{{count}} gruppiert", + "unassigned": "{{count}} nicht zugeordnet" }, "views": { "all": "Alle Konten", @@ -1288,7 +1290,11 @@ "disabled": "Deaktiviert", "deleted": "Gelöscht", "service": "Dienstkonten", - "stale": "Inaktiv (30T+)" + "stale": "Inaktiv (30T+)", + "o365": "O365", + "azure": "Azure", + "gcp": "GCP", + "aws": "AWS" }, "searchPlaceholder": "Nach Kontoname oder SID suchen…", "allTenants": "Alle Mandanten", @@ -1321,7 +1327,9 @@ "status": "Status", "lastLogon": "Letzte Anmeldung", "lastSeen": "Zuletzt gesehen", - "tenant": "Mandant" + "tenant": "Mandant", + "accountId": "Konto-ID", + "identityGroup": "Identitätsgruppe" }, "status": { "active": "Aktiv", @@ -1363,7 +1371,21 @@ "lastLogon": "Letzte Anmeldung", "lastSeen": "Zuletzt in Logs gesehen", "deleted": "Konto gelöscht", - "noLifecycle": "Keine Lebenszyklus-Ereignisse aufgezeichnet." + "noLifecycle": "Keine Lebenszyklus-Ereignisse aufgezeichnet.", + "aliasGroup": "Identitätsgruppe", + "alias": { + "add": "Identitätsgruppe hinzufügen", + "search": "Gruppen suchen…", + "none": "Noch keine Gruppen", + "new": "Neue Gruppe", + "unassign": "Aus Gruppe entfernen", + "unassigned": "Keine Gruppe", + "newPlaceholder": "Name der neuen Gruppe (2–64 Zeichen)", + "createAndAssign": "Erstellen & zuordnen", + "nameTooShort": "Gruppenname muss 2–64 Zeichen haben", + "updated": "Identitätsgruppe aktualisiert", + "updateFailed": "Identitätsgruppe konnte nicht aktualisiert werden" + } }, "relative": { "justNow": "gerade eben", @@ -1371,7 +1393,9 @@ "hoursAgo": "vor {{count}}h", "daysAgo": "vor {{count}}T" }, - "none": "—" + "none": "—", + "allIdentities": "Alle Identitätsgruppen", + "noneIdentity": "Keine Identitätsgruppe" }, "connectionKey": { "title": "Verbindungsschlüssel", @@ -3708,7 +3732,7 @@ "name": "Windows File Access Auditing", "description": "Collect Windows file access audit events through the Windows Event Log and UTMStack agent." }, - "ELASTICsearch": { + "ELASTICsearch": { "name": "ELASTICsearch", "description": "Ingesta los registros de Elasticsearch para monitorear el motor de búsqueda y análisis y sus cargas de trabajo de aplicación." } @@ -6219,9 +6243,6 @@ } }, "liveOps": { - "listNew": "Neu", - "newAlertsCount_one": "{{count}} neuer Alert", - "newAlertsCount_other": "{{count}} neue Alerts", "header": "Live-Betrieb", "live": "LIVE", "replay": "WIEDERGABE", @@ -6516,6 +6537,9 @@ "capCt2": "Befehle und Daten überschreiten die Grenze unsichtbar, auf {{proto}}.", "capCt3": "Tunnel kappen, Endpunkt blockieren und prüfen, was durchgegangen ist.", "titleCt": "{{src}} tunnelt C2 über {{proto}} zu {{to}}", + "listNew": "Neu", + "newAlertsCount_one": "{{count}} neuer Alert", + "newAlertsCount_other": "{{count}} neue Alerts", "netPerimeter": "Perimeter", "scDc": "Domain-Controller", "scObject": "Geändertes Objekt", @@ -6641,4 +6665,4 @@ "capCt2": "Befehle und Daten überschreiten die Grenze unsichtbar, auf {{proto}}.", "capCt3": "Tunnel kappen, Endpunkt blockieren und prüfen, was durchgegangen ist.", "titleCt": "{{src}} tunnelt C2 über {{proto}} zu {{to}}" -} \ No newline at end of file +} diff --git a/frontend/src/shared/i18n/locales/en.json b/frontend/src/shared/i18n/locales/en.json index 8169c3e4b..50e733f2e 100644 --- a/frontend/src/shared/i18n/locales/en.json +++ b/frontend/src/shared/i18n/locales/en.json @@ -1,6459 +1,6611 @@ { - "onboarding": { - "adminEmail": { - "title": "Set your admin email", - "subtitle": "Required before you continue", - "description": "Your administrator account still uses the default email. Set a real address — it's needed for password recovery, notifications and alert emails.", - "emailLabel": "Email address", - "save": "Save and continue", - "saving": "Saving…", - "success": "Admin email set. Next, configure your mail server.", - "error": "Could not save your email. Please try again." - } - }, - "common": { - "appName": "UTMStack", - "language": "Language", - "actions": { - "save": "Save", - "cancel": "Cancel", - "retry": "Retry", - "refresh": "Refresh", - "delete": "Delete", - "remove": "Remove", - "close": "Close", - "next": "Next", - "back": "Back" - }, - "confirm": { - "delete": "Delete", - "working": "Working…" - }, - "dateRange": { - "pick": "Pick a range", - "clear": "Clear", - "done": "Done", - "apply": "Apply" - }, - "loadingMore": "Loading more…", - "allLoaded": "All {{count}} loaded", - "startFrom": { - "scratch": "From scratch", - "scratchHint": "An empty definition you fill in yourself.", - "copy": "From an existing one", - "copyHint": "Everything is copied except the identifier and the name.", - "pickTitle": "Choose what to copy", - "back": "Back", - "count": "{{n}} available", - "search": "Search by name", - "none": "Nothing matches that search" - }, - "cancel": "Cancel" - }, - "auth": { - "login": { - "title": "Welcome back", - "subtitle": "Sign in to continue to {{brand}}", - "loginLabel": "Email", - "passwordLabel": "Password", - "forgot": "Forgot?", - "submit": "Sign in", - "terms": "By signing in, you agree to {{brand}}'s terms of service.", - "orContinueWith": "or continue with", - "continueWith": "Continue with {{name}}", - "signingInTo": "Signing in to {{name}}", - "useAnother": "Use another" - }, - "tfa": { - "title": "Two-factor verification", - "subtitleTotp": "Enter the 6-digit code from your authenticator app.", - "subtitleEmail": "Enter the 6-digit code we emailed you.", - "codeLabel": "Verification code", - "submit": "Verify", - "back": "Back to sign in" - }, - "forgot": { - "title": "Reset your password", - "subtitle": "We'll email you a link to set a new password.", - "emailLabel": "Email", - "submit": "Send reset link", - "sent": "If that email is registered, a reset link is on its way." - }, - "errors": { - "tooManyAttempts": "Too many attempts. Try again in a few minutes.", - "deactivated": "This account is deactivated.", - "invalidCredentials": "Invalid credentials.", - "codeExpired": "This code has expired. Sign in again.", - "loginFailed": "Login failed. Please try again.", - "invalidCode": "Invalid or expired code.", - "verifyFailed": "Verification failed. Please try again.", - "resetFailed": "Could not send the reset email. Please try again.", - "ssoFailed": "Single sign-on did not complete. Try again or use your password." - } - }, - "profile": { - "hero": { - "administrator": "Administrator", - "changeAvatar": "Change avatar", - "removeAvatar": "Remove avatar" - }, - "personal": { - "title": "Personal information", - "description": "Update your name and contact info.", - "firstName": "First name", - "lastName": "Last name", - "email": "Email", - "language": "Language", - "languageHint": "Used for the panel interface.", - "systemDefault": "System default", - "username": "Username", - "usernameHint": "Username cannot be changed.", - "reset": "Reset", - "save": "Save changes", - "saving": "Saving…", - "name": "Name" - }, - "password": { - "title": "Password", - "description": "Use a strong password you don't reuse anywhere else.", - "current": "Current password", - "new": "New password", - "newHint": "At least 8 characters.", - "confirm": "Confirm new password", - "update": "Update password", - "updating": "Updating…" - }, - "sessions": { - "title": "Active sessions", - "description": "Devices currently signed in to your account.", - "loading": "Loading sessions…", - "empty": "No active sessions.", - "thisDevice": "This device", - "unknownIp": "Unknown IP", - "unknownDevice": "Unknown device", - "deviceLabel": "{{browser}} on {{os}}", - "signedIn": "Signed in {{time}}", - "revoke": "Revoke", - "revoking": "Revoking…", - "signOutOthers": "Sign out of all other sessions", - "signingOut": "Signing out…" + "onboarding": { + "adminEmail": { + "title": "Set your admin email", + "subtitle": "Required before you continue", + "description": "Your administrator account still uses the default email. Set a real address — it's needed for password recovery, notifications and alert emails.", + "emailLabel": "Email address", + "save": "Save and continue", + "saving": "Saving…", + "success": "Admin email set. Next, configure your mail server.", + "error": "Could not save your email. Please try again." + } }, - "tfa": { - "title": "Two-factor authentication", - "description": "Add an extra layer of security to your account.", - "loading": "Loading…", - "methodTotp": "Authenticator app", - "methodEmail": "Email code", - "onTitle": "Two-factor authentication is on", - "method": "Method: {{method}}", - "configured": "Configured", - "disable": "Disable", - "disableTitle": "Disable two-factor authentication", - "disableDescription": "Enter your current password to confirm. Your account will rely on the password alone afterwards.", - "currentPasswordPlaceholder": "Current password", - "disableConfirm": "Disable 2FA", - "disabling": "Disabling…", - "offTitle": "Two-factor authentication is off", - "status": "Status:", - "notConfigured": "Not configured", - "enable": "Enable", - "chooseMethod": "Choose a method", - "totpDesc": "Use Google Authenticator, 1Password, etc. Recommended.", - "emailDesc": "Receive a 6-digit code by email at sign-in.", - "noEmailHint": "Add an email to your profile to use the email method.", - "continue": "Continue", - "starting": "Starting…", - "scanTitle": "Scan the QR code", - "scanDescription": "Scan it with your authenticator app, then enter the 6-digit code it shows.", - "manualKey": "Or enter this key manually:", - "checkEmailTitle": "Check your email", - "checkEmailDescription": "We sent a 6-digit code to {{email}}. Enter it below.", - "resend": "Resend", - "verifyEnable": "Verify & enable", - "verifying": "Verifying…" + "common": { + "appName": "UTMStack", + "language": "Language", + "actions": { + "save": "Save", + "cancel": "Cancel", + "retry": "Retry", + "refresh": "Refresh", + "delete": "Delete", + "remove": "Remove", + "close": "Close", + "next": "Next", + "back": "Back" + }, + "confirm": { + "delete": "Delete", + "working": "Working…" + }, + "dateRange": { + "pick": "Pick a range", + "clear": "Clear", + "done": "Done", + "apply": "Apply" + }, + "loadingMore": "Loading more…", + "allLoaded": "All {{count}} loaded", + "startFrom": { + "scratch": "From scratch", + "scratchHint": "An empty definition you fill in yourself.", + "copy": "From an existing one", + "copyHint": "Everything is copied except the identifier and the name.", + "pickTitle": "Choose what to copy", + "back": "Back", + "count": "{{n}} available", + "search": "Search by name", + "none": "Nothing matches that search" + }, + "cancel": "Cancel" + }, + "auth": { + "login": { + "title": "Welcome back", + "subtitle": "Sign in to continue to {{brand}}", + "loginLabel": "Email", + "passwordLabel": "Password", + "forgot": "Forgot?", + "submit": "Sign in", + "terms": "By signing in, you agree to {{brand}}'s terms of service.", + "orContinueWith": "or continue with", + "continueWith": "Continue with {{name}}", + "signingInTo": "Signing in to {{name}}", + "useAnother": "Use another" + }, + "tfa": { + "title": "Two-factor verification", + "subtitleTotp": "Enter the 6-digit code from your authenticator app.", + "subtitleEmail": "Enter the 6-digit code we emailed you.", + "codeLabel": "Verification code", + "submit": "Verify", + "back": "Back to sign in" + }, + "forgot": { + "title": "Reset your password", + "subtitle": "We'll email you a link to set a new password.", + "emailLabel": "Email", + "submit": "Send reset link", + "sent": "If that email is registered, a reset link is on its way." + }, + "errors": { + "tooManyAttempts": "Too many attempts. Try again in a few minutes.", + "deactivated": "This account is deactivated.", + "invalidCredentials": "Invalid credentials.", + "codeExpired": "This code has expired. Sign in again.", + "loginFailed": "Login failed. Please try again.", + "invalidCode": "Invalid or expired code.", + "verifyFailed": "Verification failed. Please try again.", + "resetFailed": "Could not send the reset email. Please try again.", + "ssoFailed": "Single sign-on did not complete. Try again or use your password." + } }, - "actions": { - "cancel": "Cancel" + "profile": { + "hero": { + "administrator": "Administrator", + "changeAvatar": "Change avatar", + "removeAvatar": "Remove avatar" + }, + "personal": { + "title": "Personal information", + "description": "Update your name and contact info.", + "firstName": "First name", + "lastName": "Last name", + "email": "Email", + "language": "Language", + "languageHint": "Used for the panel interface.", + "systemDefault": "System default", + "username": "Username", + "usernameHint": "Username cannot be changed.", + "reset": "Reset", + "save": "Save changes", + "saving": "Saving…", + "name": "Name" + }, + "password": { + "title": "Password", + "description": "Use a strong password you don't reuse anywhere else.", + "current": "Current password", + "new": "New password", + "newHint": "At least 8 characters.", + "confirm": "Confirm new password", + "update": "Update password", + "updating": "Updating…" + }, + "sessions": { + "title": "Active sessions", + "description": "Devices currently signed in to your account.", + "loading": "Loading sessions…", + "empty": "No active sessions.", + "thisDevice": "This device", + "unknownIp": "Unknown IP", + "unknownDevice": "Unknown device", + "deviceLabel": "{{browser}} on {{os}}", + "signedIn": "Signed in {{time}}", + "revoke": "Revoke", + "revoking": "Revoking…", + "signOutOthers": "Sign out of all other sessions", + "signingOut": "Signing out…" + }, + "tfa": { + "title": "Two-factor authentication", + "description": "Add an extra layer of security to your account.", + "loading": "Loading…", + "methodTotp": "Authenticator app", + "methodEmail": "Email code", + "onTitle": "Two-factor authentication is on", + "method": "Method: {{method}}", + "configured": "Configured", + "disable": "Disable", + "disableTitle": "Disable two-factor authentication", + "disableDescription": "Enter your current password to confirm. Your account will rely on the password alone afterwards.", + "currentPasswordPlaceholder": "Current password", + "disableConfirm": "Disable 2FA", + "disabling": "Disabling…", + "offTitle": "Two-factor authentication is off", + "status": "Status:", + "notConfigured": "Not configured", + "enable": "Enable", + "chooseMethod": "Choose a method", + "totpDesc": "Use Google Authenticator, 1Password, etc. Recommended.", + "emailDesc": "Receive a 6-digit code by email at sign-in.", + "noEmailHint": "Add an email to your profile to use the email method.", + "continue": "Continue", + "starting": "Starting…", + "scanTitle": "Scan the QR code", + "scanDescription": "Scan it with your authenticator app, then enter the 6-digit code it shows.", + "manualKey": "Or enter this key manually:", + "checkEmailTitle": "Check your email", + "checkEmailDescription": "We sent a 6-digit code to {{email}}. Enter it below.", + "resend": "Resend", + "verifyEnable": "Verify & enable", + "verifying": "Verifying…" + }, + "actions": { + "cancel": "Cancel" + }, + "toast": { + "profileUpdated": "Profile updated", + "emailInUse": "That email is already in use", + "profileUpdateFailed": "Could not update profile", + "passwordsNoMatch": "Passwords do not match", + "passwordTooShort": "Password must be at least 8 characters", + "passwordChanged": "Password changed — other sessions were signed out", + "currentPasswordWrong": "Current password is incorrect", + "passwordChangeFailed": "Could not change password", + "avatarTypeNotAllowed": "Image type not allowed (use PNG, JPEG, WEBP or GIF)", + "avatarTooLarge": "Image is too large (max 2MB)", + "avatarUpdated": "Avatar updated", + "avatarUploadFailed": "Could not upload avatar", + "avatarRemoved": "Avatar removed", + "avatarRemoveFailed": "Could not remove avatar", + "sessionsLoadFailed": "Could not load sessions", + "sessionRevoked": "Session revoked", + "sessionRevokeFailed": "Could not revoke session", + "othersSignedOut": "Other sessions signed out", + "othersRevokeFailed": "Could not revoke sessions", + "tfaEmailCodeSent": "We sent a 6-digit code to your email", + "tfaNewCodeSent": "A new code was sent", + "tfaWaitResend": "Please wait a moment before requesting a new code", + "tfaResendFailed": "Could not resend the code", + "tfaEnterCode": "Enter the 6-digit code", + "tfaEnabled": "Two-factor authentication enabled", + "tfaEnterPassword": "Enter your current password", + "tfaDisabled": "Two-factor authentication disabled", + "tfaDisableFailed": "Could not disable 2FA", + "tfaInvalidCode": "Invalid or expired code", + "tfaAlreadyEnabled": "2FA is already enabled", + "tfaTooManyRequests": "Too many requests; try again shortly", + "tfaVerifyFailed": "Could not verify the code", + "genericError": "Something went wrong", + "tfaMailUnavailable": "Two-factor by email needs a mail server. Configure it in Settings → Email Configuration." + } }, - "toast": { - "profileUpdated": "Profile updated", - "emailInUse": "That email is already in use", - "profileUpdateFailed": "Could not update profile", - "passwordsNoMatch": "Passwords do not match", - "passwordTooShort": "Password must be at least 8 characters", - "passwordChanged": "Password changed — other sessions were signed out", - "currentPasswordWrong": "Current password is incorrect", - "passwordChangeFailed": "Could not change password", - "avatarTypeNotAllowed": "Image type not allowed (use PNG, JPEG, WEBP or GIF)", - "avatarTooLarge": "Image is too large (max 2MB)", - "avatarUpdated": "Avatar updated", - "avatarUploadFailed": "Could not upload avatar", - "avatarRemoved": "Avatar removed", - "avatarRemoveFailed": "Could not remove avatar", - "sessionsLoadFailed": "Could not load sessions", - "sessionRevoked": "Session revoked", - "sessionRevokeFailed": "Could not revoke session", - "othersSignedOut": "Other sessions signed out", - "othersRevokeFailed": "Could not revoke sessions", - "tfaEmailCodeSent": "We sent a 6-digit code to your email", - "tfaNewCodeSent": "A new code was sent", - "tfaWaitResend": "Please wait a moment before requesting a new code", - "tfaResendFailed": "Could not resend the code", - "tfaEnterCode": "Enter the 6-digit code", - "tfaEnabled": "Two-factor authentication enabled", - "tfaEnterPassword": "Enter your current password", - "tfaDisabled": "Two-factor authentication disabled", - "tfaDisableFailed": "Could not disable 2FA", - "tfaInvalidCode": "Invalid or expired code", - "tfaAlreadyEnabled": "2FA is already enabled", - "tfaTooManyRequests": "Too many requests; try again shortly", - "tfaVerifyFailed": "Could not verify the code", - "genericError": "Something went wrong", - "tfaMailUnavailable": "Two-factor by email needs a mail server. Configure it in Settings → Email Configuration." - } - }, - "home": { - "hero": { - "title": "What would you like to know from your security data?", - "placeholder": "Research Scattered Spider, does it apply to us, have we ever been hit, build a detection rule and keep it tuned.", - "send": "Send", - "suggestions": { - "threatHunt": "Threat hunt", - "observableTriage": "Observable triage", - "writeRule": "Write a rule", - "systemStatus": "Current system status" - } + "home": { + "hero": { + "title": "What would you like to know from your security data?", + "placeholder": "Research Scattered Spider, does it apply to us, have we ever been hit, build a detection rule and keep it tuned.", + "send": "Send", + "suggestions": { + "threatHunt": "Threat hunt", + "observableTriage": "Observable triage", + "writeRule": "Write a rule", + "systemStatus": "Current system status" + } + }, + "kpis": { + "alerts24h": "Alerts (24h)", + "openIncidents": "Open incidents", + "openIncidentsSub": "currently open", + "highSeverity24h": "High severity (24h)", + "highSeveritySub": "of {{n}} alerts", + "activePlaybooks": "Active playbooks", + "activePlaybooksSub": "enabled" + }, + "datasources": { + "title": "Datasources", + "viewAll": "View all", + "ofTotal": "of {{n}}", + "datasources": "datasources", + "sendingData": "sending data", + "totalEvents": "Total events", + "noData": "No ingestion data in this window" + }, + "span": { + "recent": "recent window", + "days_one": "last {{count}} day", + "days_other": "last {{count}} days", + "hours": "last {{n}}h" + }, + "mitre": { + "title": "Top MITRE ATT&CK techniques", + "explore": "Explore", + "empty": "No technique-tagged alerts yet" + }, + "assets": { + "title": "Top targeted assets", + "viewAll": "View all", + "asset": "Asset", + "alerts": "Alerts", + "empty": "No targeted assets in recent alerts" + }, + "compliance": { + "title": "Compliance score", + "reports": "Reports", + "empty": "No compliance reports generated yet" + }, + "health": { + "title": "System health", + "details": "Details", + "services": { + "backend": "Backend API", + "opensearch": "OpenSearch cluster", + "socai": "SOC-AI engine" + }, + "detail": { + "noClusterInfo": "no cluster info", + "disabled": "disabled", + "tools": "{{n}} tools", + "unreachable": "unreachable", + "pending": "…" + } + } }, - "kpis": { - "alerts24h": "Alerts (24h)", - "openIncidents": "Open incidents", - "openIncidentsSub": "currently open", - "highSeverity24h": "High severity (24h)", - "highSeveritySub": "of {{n}} alerts", - "activePlaybooks": "Active playbooks", - "activePlaybooksSub": "enabled" + "nav": { + "openMenu": "Open menu", + "closeMenu": "Close menu", + "home": "Home", + "dashboards": "Dashboards", + "dashboardList": "Dashboard list", + "visualizationList": "Widget list", + "newDashboard": "New dashboard", + "newVisualization": "New widget", + "threatManagement": "Threat Management", + "alerts": "Alerts", + "taggingRules": "Tagging Rules", + "incidents": "Incidents", + "adversaryView": "Adversary View", + "soar": "SOAR", + "flows": "Flows", + "executionHistory": "Execution history", + "interactiveConsole": "Interactive Console", + "logExplorer": "Log Explorer", + "userAuditor": "User Auditor", + "threatIntelligence": "Threat Intelligence", + "threat-intel": { + "indicators": "Indicators", + "analyzt": "AI Analyst", + "triage": "Triage", + "report": "Report" + }, + "compliance": "Compliance", + "configure": "Configure", + "dataSources": "Data Sources", + "integrations": "Integrations", + "alertingRules": "Alerting Rules", + "dataProcessing": "Data Processing", + "team": "Team", + "settings": "Settings", + "back": "Back", + "parsingFilters": "Pipelines", + "regexPatterns": "Regex Patterns", + "overview": "Overview", + "tenants": "Tenants", + "liveOps": "Live Operations" }, - "datasources": { - "title": "Datasources", - "viewAll": "View all", - "ofTotal": "of {{n}}", - "datasources": "datasources", - "sendingData": "sending data", - "totalEvents": "Total events", - "noData": "No ingestion data in this window" + "dashboards": { + "title": "Dashboards", + "subtitle": "Browse and edit interactive dashboards.", + "list": { + "title": "Dashboards", + "create": "New", + "searchPlaceholder": "Search dashboards…", + "loading": "Loading dashboards…", + "empty": "No dashboards yet.", + "rename": "Rename", + "delete": "Delete" + }, + "actions": { + "edit": "Edit", + "editWithAi": "Edit with AI" + }, + "refresh": { + "title": "Auto refresh", + "options": { + "off": "Off", + "10s": "10s", + "30s": "30s", + "1m": "1m", + "5m": "5m", + "15m": "15m" + } + }, + "editor": { + "editing": "Editing", + "addWidget": "Add widget", + "editFilters": "Edit filters", + "save": "Save", + "discard": "Discard", + "newTitle": "New widget", + "newSubtitle": "Pick a chart type, choose a data source, and shape it visually. SQL is generated for you.", + "editTitle": "Edit widget", + "editSubtitle": "Tweak the chart definition. Changes apply everywhere this widget is used.", + "loading": "Loading widget…", + "notFoundTitle": "Widget not found", + "notFoundSubtitle": "It may have been deleted or you may not have access.", + "backToDashboard": "Back to dashboard", + "chartType": { + "title": "Chart type" + }, + "chartTypes": { + "bar": { + "label": "Bar", + "description": "Compare values across categories." + }, + "line": { + "label": "Line", + "description": "Trends over an ordered axis." + }, + "area": { + "label": "Area", + "description": "Filled line — emphasises volume." + }, + "pie": { + "label": "Pie", + "description": "Share of a whole by category." + }, + "metric": { + "label": "Metric", + "description": "A single scalar value." + }, + "table": { + "label": "Table", + "description": "Aggregated rows." + }, + "list": { + "label": "List", + "description": "Raw, non-aggregated rows." + }, + "region_map": { + "label": "Coordinate map", + "description": "Plot markers on a world map using lat/lon coordinates." + }, + "text": { + "label": "Text", + "description": "Free-form text or plain row output." + } + }, + "dataSource": { + "title": "Which data?", + "dataset": "Data set", + "noDatasetHint": "Choose a data set to enable conditions and grouping." + }, + "widgetTitle": { + "label": "Title", + "placeholder": "Optional — defaults to the chart type" + }, + "dataset": { + "placeholder": "Select a data set…", + "loading": "Loading data sets…" + }, + "filters": { + "title": "Include only events where…", + "empty": "No conditions — all events in the time range are included.", + "add": "Add condition", + "remove": "Remove", + "field": "Field", + "fieldPlaceholder": "e.g. host.name", + "operator": "Operator", + "value": "Value", + "valuePlaceholder": "Value", + "from": "From", + "to": "To", + "noValue": "No value needed", + "listPlaceholder": "Comma-separated values" + }, + "operators": { + "IS": "is", + "IS_NOT": "is not", + "IS_ONE_OF_TERMS": "is one of", + "IS_GREATER_THAN": "is greater than", + "IS_LESS_THAN_OR_EQUALS": "is less than or equals", + "IS_BETWEEN": "is between", + "CONTAIN": "contains", + "DOES_NOT_CONTAIN": "does not contain", + "START_WITH": "starts with", + "ENDS_WITH": "ends with", + "EXIST": "exists", + "DOES_NOT_EXIST": "does not exist" + }, + "dimension": { + "title": "Group by", + "field": "Field", + "placeholder": "Pick a field to group by…" + }, + "table": { + "hint": "Shows every field the records carry. Add columns to pick specific ones.", + "columnsTitle": "Columns", + "allColumns": "All columns will be shown. Add fields to pick specific ones.", + "addColumn": "Add a column…", + "removeColumn": "Remove column" + }, + "chartPreview": { + "title": "Chart preview", + "noQuery": "Pick a data set to see a preview.", + "error": "Preview query failed." + }, + "chartTypeChip": { + "label": "Chart:" + }, + "chartTypeModal": { + "title": "Pick a chart type", + "subtitle": "Choose how to visualize the data. You can change this later.", + "confirm": "Continue", + "swapTitle": "Change chart type", + "swapConfirm": "Apply" + }, + "saveVisualization": "Save widget", + "fieldSelect": { + "loading": "Loading fields…", + "choose": "Choose a field…" + }, + "toast": { + "notReady": "Pick a data set, and a field to break down by, before saving." + }, + "breakdown": { + "title": "Break down by", + "topValuesTable": "Top values table", + "time": "Over time", + "field": "Top values", + "interval": "Bucket size", + "intervalAuto": "Auto", + "limit": "How many", + "limitPlaceholder": "Default (50)", + "splitHint": "Optional: one line per value of this field." + } + }, + "grid": { + "empty": "This dashboard has no widgets yet.", + "missingVisualization": "Widget unavailable", + "unknownVisualization": "Widget" + }, + "widget": { + "renderError": "Could not render this widget.", + "count": "Count", + "loading": "Loading data…", + "queryError": "Could not load widget data.", + "noData": "No data for the selected time range.", + "regionMapEmpty": "No points with valid lat/lon.", + "regionMapShapeHint": "The SQL must return latitude and longitude columns (or a value array [lat, lon, count]).", + "regionMapUnnamed": "(unnamed)", + "regionMapValue": "value: {{value}}", + "editAriaLabel": "Edit widget", + "removeAriaLabel": "Remove widget", + "moveBack": "Move back", + "moveForward": "Move forward", + "width": "Width", + "height": "Height", + "widthSmall": "1 col", + "widthMedium": "2 cols", + "widthLarge": "3 cols", + "heightNormal": "Normal", + "heightTall": "Tall", + "incompleteSpec": "This widget is missing part of its question." + }, + "form": { + "createTitle": "New dashboard", + "renameTitle": "Edit dashboard", + "name": "Name", + "namePlaceholder": "e.g. Network overview", + "description": "Description", + "descriptionPlaceholder": "Optional", + "cancel": "Cancel", + "create": "Create", + "save": "Save" + }, + "confirm": { + "deleteTitle": "Delete dashboard", + "delete": "Delete dashboard \"{{name}}\"? This cannot be undone.", + "deleteWidgetsTitle": "Delete widgets", + "deleteWidgets_one": "Delete this widget? This cannot be undone.", + "deleteWidgets_other": "Delete {{count}} widgets? This cannot be undone.", + "dismissTitle": "Remove dashboard", + "dismiss": "Remove the default dashboard \"{{name}}\"? You can start a new one from it later — \"New\" → \"From an existing one\"." + }, + "page": { + "noSelection": "Pick a dashboard from the list, or create one to get started.", + "loading": "Loading widgets…" + }, + "toast": { + "created": "Dashboard created.", + "createFailed": "Could not create dashboard.", + "updated": "Dashboard updated.", + "updateFailed": "Could not update dashboard.", + "deleted": "Dashboard deleted.", + "deleteFailed": "Could not delete dashboard.", + "layoutSaved": "Layout saved.", + "layoutSaveFailed": "Could not save layout.", + "visualizationCreated": "Widget created.", + "visualizationCreateFailed": "Could not create widget.", + "visualizationUpdated": "Widget updated.", + "visualizationUpdateFailed": "Could not update widget.", + "visualizationDeleted": "Widget deleted.", + "visualizationDeleteFailed": "Could not delete widget.", + "filtersSaved": "Filters saved.", + "filtersSaveFailed": "Could not save filters.", + "filterCreated": "Filter created.", + "filterUpdated": "Filter updated.", + "filterDeleted": "Filter deleted.", + "filterCreateFailed": "Could not create filter.", + "filterUpdateFailed": "Could not update filter.", + "filterDeleteFailed": "Could not delete filter." + }, + "filters": { + "chooseValue": "Choose…", + "selected": "selected", + "loading": "Loading values…", + "searchPlaceholder": "Search values…", + "noValues": "No values available.", + "loadError": "Could not load values.", + "clear": "Clear", + "editorTitle": "Dashboard filters", + "editorHint": "Add dropdown chips that filter every widget on this dashboard.", + "emptyEditor": "No filter chips yet. Add one to get started.", + "addChip": "Add filter", + "cancel": "Cancel", + "save": "Save", + "field": { + "dataset": "Data set", + "field": "Field", + "chooseField": "Choose a field…", + "label": "Label", + "labelPlaceholder": "e.g. Host", + "placeholder": "Placeholder", + "placeholderPlaceholder": "e.g. Pick a host", + "multiple": "Multiple", + "searchable": "Searchable" + }, + "addTitle": "Add filter", + "editTitle": "Edit filter", + "removeTitle": "Remove filter", + "removeConfirm": "Remove filter \"{{label}}\"? This cannot be undone.", + "remove": "Remove", + "editAria": "Edit filter", + "removeAria": "Remove filter", + "saving": "Saving…" + }, + "newDashboard": { + "title": "New dashboard", + "subtitle": "Create a blank dashboard. You can add widgets after it's saved.", + "modeManual": "Create manually", + "modeAi": "Using AI", + "aiLocked": "Enable SOC-AI and configure it to use this.", + "aiDescriptionLabel": "What should this dashboard show?", + "aiDescriptionPlaceholder": "e.g. Failed logins by country, last 7 days", + "aiCreate": "Create with AI", + "aiOpenerWithDetails": "Create a dashboard named \"{{name}}\" showing: {{description}}" + }, + "newVisualization": { + "title": "New widget", + "subtitle": "Define a reusable chart from a SQL query and an ECharts option config.", + "sqlQuery": "SQL query", + "sqlQueryPlaceholder": "SELECT bucket, count(*) FROM logs GROUP BY bucket", + "sqlQueryHint": "Use the placeholders timeFilter, from, and to (in double curly braces) so the time picker is applied at render time.", + "config": "Chart config (ECharts option, JSON)", + "configHint": "Must be valid JSON. Rows from the SQL are exposed as `dataset.source` — wire your series with `encode`.", + "configError": "Invalid JSON: {{error}}" + }, + "visualizationList": { + "title": "Widgets", + "subtitle": "{{count}} widget(s) available.", + "subtitleFiltered": "Showing {{shown}} of {{total}}.", + "create": "New", + "searchPlaceholder": "Search widgets…", + "loading": "Loading widgets…", + "empty": "No widgets yet.", + "emptyFiltered": "No widgets match the current filters.", + "delete": "Delete", + "deleteTitle": "Delete widget", + "confirmDelete": "Delete widget \"{{name}}\"? This cannot be undone.", + "filters": { + "search": "Search", + "chartType": "Chart type", + "allChartTypes": "All chart types", + "source": "Source", + "allSources": "All sources", + "createdAt": "Created", + "modifiedAt": "Modified", + "createdRangeTitle": "Custom range — Created", + "modifiedRangeTitle": "Custom range — Modified", + "pickRange": "Pick a range", + "datePresets": { + "all": "All time", + "today": "Today", + "last7": "Last 7 days", + "last30": "Last 30 days", + "lastYear": "Last year", + "custom": "Custom range" + }, + "clear": "Clear filters" + }, + "col": { + "name": "Name", + "chartType": "Chart type", + "source": "Source", + "description": "Description", + "created": "Created", + "modified": "Modified" + } + }, + "tabs": { + "dashboards": "Dashboards", + "visualizations": "Widgets", + "newDashboard": "New dashboard", + "unsetDefault": "Unset default", + "options": "Options" + }, + "picker": { + "none": "Select dashboard", + "search": "Search dashboards…", + "new": "New dashboard", + "setDefault": "Set as default", + "empty": "No dashboards" + }, + "empty": { + "title": "No dashboards yet", + "body": "Create your first dashboard to see your security data at a glance.", + "cta": "Create dashboard" + }, + "duplicate": { + "copyName": "{{name}} (copy)" + } }, - "span": { - "recent": "recent window", - "days_one": "last {{count}} day", - "days_other": "last {{count}} days", - "hours": "last {{n}}h" + "settings": { + "title": "Settings", + "license": "License", + "notifications": "Notifications", + "connectionKey": "Connection Key", + "dataRetention": "Data Retention", + "indices": "Indices", + "theme": "Theme", + "branding": "Branding", + "apiKeys": "API Keys", + "identityProviders": "Identity Providers", + "email": "Email Configuration", + "dateFormat": "Date Format", + "language": "Language", + "auditLogs": "App Audit Logs", + "about": "About", + "socAi": "SOC-AI", + "supportAccess": "Support access", + "threatwinds": "ThreatWinds Integration" + }, + "topbar": { + "theme": { + "light": "Light mode", + "dark": "Dark mode" + }, + "manageLicense": "Manage license", + "profile": { + "profile": "Profile", + "license": "License", + "logout": "Log out" + } }, - "mitre": { - "title": "Top MITRE ATT&CK techniques", - "explore": "Explore", - "empty": "No technique-tagged alerts yet" + "threatIntel": { + "header": { + "matchedInEnv": "matched in your env", + "export": "Export IOCs", + "exporting": "Exporting…", + "noInstanceIocs": "No instance indicators — showing generic data", + "noInstanceIocsHint": "No indicators observed in your alerts — showing generic feed data." + }, + "overview": { + "title": "IOC matches", + "totalIndicators": "total indicators", + "families": { + "ip": "IP", + "url": "URL", + "domain": "Domain", + "signatures": "Signatures" + } + }, + "notConfigured": { + "title": "Threat Intelligence isn't configured", + "body": "Contact your administrator to connect an upstream Cyber Mantra / ThreatWinds instance for this environment." + }, + "lookup": { + "title": "Lookup any indicator", + "placeholder": "Paste an IP, domain, hash, URL, or CVE — we'll check feeds and your environment", + "button": "Lookup", + "busy": "Searching…" + }, + "tabs": { + "iocs": "IOCs", + "actors": "Threat actors", + "feeds": "Feeds", + "analyst": "AI Analyst" + }, + "toolbar": { + "searchPlaceholders": { + "iocs": "Search IOC value, tag, source…", + "actors": "Search actors, aliases, techniques…", + "feeds": "Search feeds…" + }, + "last24h": "Last 24 hours", + "filters": "Filters", + "refresh": "Refresh" + }, + "iocs": { + "table": { + "type": "Type", + "indicator": "Indicator", + "reputation": "Reputation", + "tags": "Tags", + "lastSeen": "Last seen" + }, + "empty": "No IOCs match.", + "loadingMore": "Loading more…", + "loadedProgress": "Loaded {{loaded}} of {{total}}. Scroll for more.", + "endOfResults": "End of results ({{loaded}} of {{total}})." + }, + "drawer": { + "loading": "Loading…", + "accuracy": "Accuracy:", + "actions": { + "block": "Block at perimeter", + "viewEvents": "View matched events", + "externalLookup": "External lookup", + "trackCampaign": "Track campaign", + "viewIocs": "View matched IOCs", + "mitre": "MITRE ATT&CK" + }, + "sections": { + "timeline": "Timeline", + "networkOrigin": "Network / origin", + "associationsWithCount": "Associations ({{count}})", + "geolocationsWithCount": "Geolocations ({{count}})", + "about": "About", + "activity": "Activity" + }, + "fields": { + "firstSeen": "First seen", + "lastSeen": "Last seen", + "country": "Country", + "city": "City", + "aso": "ASO", + "asn": "ASN", + "reputation": "Reputation", + "accuracy": "Accuracy", + "current": "Current", + "best": "Best", + "worst": "Worst" + }, + "aiBrief": "AI brief", + "noDescription": "No description available for this indicator.", + "lastObserved": "Last observed {{when}}." + }, + "actors": { + "empty": "No actors found." + }, + "feeds": { + "empty": "No feeds configured.", + "table": { + "name": "Feed", + "type": "Type", + "accuracy": "Accuracy", + "header": "Feeds", + "format": "Format" + }, + "download": "Download feed", + "checksum": "Checksum" + }, + "entityTypes": { + "ip": "IP", + "hostname": "Host", + "domain": "Domain", + "url": "URL", + "hash": "Hash", + "cve": "CVE", + "threat": "Threat", + "entity": "Entity" + }, + "reputation": { + "alarming": "Alarming", + "suspicious": "Suspicious", + "indefinable": "Indefinable", + "fair": "Fair", + "trustworthy": "Trustworthy" + }, + "feedAccuracy": { + "level1": "Level 1", + "level2": "Level 2", + "level3": "Level 3" + }, + "triage": { + "title": "Triage", + "subtitle": "Paste indicators, get verdicts", + "input": "Indicators", + "placeholder": "Paste IPs, domains, URLs or hashes — one per line, or comma separated.\nDefanged values (1.2.3[.]4, hxxp://) are accepted.", + "run": "Triage", + "stop": "Stop", + "reset": "Clear", + "parsed": "{{count}} unique indicators", + "capped": "Capped at {{max}} per run.", + "progress": "{{done}} of {{total}}", + "empty": "Paste indicators above to begin.", + "indicator": "Indicator", + "type": "Type", + "verdict": "Verdict", + "reputation": "Rep", + "accuracy": "Acc", + "tags": "Tags", + "lastSeen": "Last seen", + "exportCsv": "Export CSV", + "exportStix": "Export STIX", + "stixNote": "STIX export includes malicious and suspicious rows only.", + "open": "Open", + "notConfigured": "Threat intelligence is not configured — triage needs an upstream ThreatWinds instance.", + "v.malicious": "Malicious", + "v.suspicious": "Suspicious", + "v.benign": "Benign", + "v.unknown": "Unknown", + "v.notFound": "Not found", + "v.invalid": "Unrecognised", + "summary": "Summary" + }, + "report": { + "title": "Report", + "subtitle": "Publish an indicator to the ThreatWinds graph", + "submit": "Report indicator", + "submitting": "Reporting…", + "error": { + "generic": "Could not submit the indicator. Try again." + }, + "value": { + "label": "Indicator", + "placeholder": "IP, domain, URL, hash or email address" + }, + "type": { + "label": "Type", + "placeholder": "Inferred from the value", + "inferred": "Inferred: {{type}}", + "inferenceFailed": "No type could be inferred from this value. Choose one from the list, or type it.", + "unknown": "“{{type}}” is not an entity type. Choose one from the list." + }, + "tags": { + "label": "Tags", + "placeholder": "phishing, credential-theft" + }, + "description": { + "label": "Notes" + }, + "reputation": { + "legend": "Reputation", + "hint": "Leave unset if you have not reached a verdict.", + "alarming": "Alarming", + "worrying": "Worrying", + "concerning": "Concerning", + "indefinable": "Indefinable", + "adequate": "Adequate", + "good": "Good", + "exceptional": "Exceptional" + }, + "associations": { + "legend": "Related indicators", + "add": "Add related indicator", + "remove": "Remove", + "valuePlaceholder": "Related value", + "typePlaceholder": "Type (optional)", + "modeLabel": "Relationship", + "mode": { + "association": "Related to", + "aggregation": "Part of" + }, + "visibilityConflict": "This shares no visibility group with the indicator above. The whole submission would be rejected." + }, + "attributes": { + "legend": "Details", + "hint": "Optional. Anything left blank is not submitted.", + "invalidHex": "Expected {{length}} hexadecimal characters.", + "invalidHexAny": "Expected hexadecimal characters only.", + "invalidNumber": "Expected a number." + }, + "correlate": { + "legend": "Correlate", + "hint": "Each ticked attribute is published as its own entity, linked to this one.", + "count_one": "Creates {{count}} linked entity.", + "count_other": "Creates {{count}} linked entities." + }, + "scan": { + "notice": "Reporting this also queues a scan of the target." + }, + "receipt": { + "title": "Submitted", + "noVerdict": "No verdict stated", + "skipped": "Not submitted, no type could be inferred", + "pending": "Waiting for the indicator to appear in the corpus…", + "live": "Live in the corpus — view entity", + "processing": "Still being processed. It will appear once ingestion catches up.", + "another": "Report another" + }, + "visibility": { + "legend": "Visible to" + }, + "example": "Try example" + } }, - "assets": { - "title": "Top targeted assets", - "viewAll": "View all", - "asset": "Asset", - "alerts": "Alerts", - "empty": "No targeted assets in recent alerts" + "notifications": { + "title": "Notifications", + "markAllRead": "Mark all read", + "empty": "You have no notifications.", + "viewAll": "View all", + "markRead": "Mark as read", + "markUnread": "Mark as unread", + "delete": "Delete", + "subtitle": "{{total}} total · {{unread}} unread", + "allCaughtUp": "All caught up.", + "loadFailed": "Could not load notifications." }, - "compliance": { - "title": "Compliance score", - "reports": "Reports", - "empty": "No compliance reports generated yet" + "pagination": { + "perPage": "Per page", + "pageOf": "Page {{page}} of {{total}}", + "previous": "Previous", + "next": "Next" }, - "health": { - "title": "System health", - "details": "Details", - "services": { - "backend": "Backend API", - "opensearch": "OpenSearch cluster", - "socai": "SOC-AI engine" - }, - "detail": { - "noClusterInfo": "no cluster info", - "disabled": "disabled", - "tools": "{{n}} tools", - "unreachable": "unreachable", - "pending": "…" - } - } - }, - "nav": { - "openMenu": "Open menu", - "closeMenu": "Close menu", - "home": "Home", - "dashboards": "Dashboards", - "dashboardList": "Dashboard list", - "visualizationList": "Widget list", - "newDashboard": "New dashboard", - "newVisualization": "New widget", - "threatManagement": "Threat Management", - "alerts": "Alerts", - "taggingRules": "Tagging Rules", - "incidents": "Incidents", - "adversaryView": "Adversary View", - "soar": "SOAR", - "flows": "Flows", - "executionHistory": "Execution history", - "interactiveConsole": "Interactive Console", - "logExplorer": "Log Explorer", - "userAuditor": "User Auditor", - "threatIntelligence": "Threat Intelligence", - "threat-intel": { - "indicators": "Indicators", - "analyzt": "AI Analyst", - "triage": "Triage", - "report": "Report" + "license": { + "title": "License", + "subtitle": "Your edition, capabilities, and license file.", + "loading": "Loading license…", + "loadError": "Could not load license information.", + "statusLabel": "Status", + "status": { + "community": "Community", + "active": "Active", + "expiring": "Expiring soon", + "expired": "Expired" + }, + "edition": "Edition", + "enterprise": "Enterprise", + "community": "Community", + "editionLine": "{{edition}} edition", + "datasourceLimit": "Datasource limit", + "unlimited": "Unlimited", + "mssp": "MSSP / multi-tenant", + "enabled": "Enabled", + "licenseType": "License type", + "instanceId": "Instance ID", + "enterpriseUnlocked": "Enterprise features unlocked", + "validUntil": "Valid until", + "noExpiry": "No expiry", + "timeRemaining": "Time remaining", + "expiredAgo": "Expired {{days}}d ago", + "daysShort": "{{days}}d", + "msspShort": "MSSP", + "communityEdition": "Community edition", + "communityBlurb": "Free and open-source. Upload an Enterprise license below to unlock multi-tenancy, SSO, higher datasource limits, and advanced compliance.", + "upgrade": "Upgrade to Enterprise", + "uploadTitle": "Upload a license", + "uploadBlurb": "Install or replace the signed LICENSE file. The server validates the signature and expiry before applying it. Admin only.", + "installLicense": "Install license", + "chooseFile": "Choose file", + "noFileSelected": "No file selected", + "toast": { + "installed": "License installed — {{edition}} edition.", + "adminRequired": "Administrator privileges are required to upload a license.", + "invalid": "Invalid or expired license file.", + "installFailed": "Could not install the license." + }, + "ingestLimit": "Ingest volume", + "notMetered": "Not metered", + "gbPerMonth": "{{gb}} GB/month" + }, + "audit": { + "title": "Audit log", + "subtitle": "Record of every security-relevant action.", + "totalEntries": "{{total}} total entries.", + "loadError": "Could not load audit log", + "stats": { + "totalEntries": "Total entries", + "acrossAllTime": "Across all time", + "successRate": "Success rate", + "failuresOnPage_one": "{{count}} failure on this page", + "failuresOnPage_other": "{{count}} failures on this page", + "topAction": "Top action", + "onPage": "{{count}} on this page", + "uniqueActors": "Unique actors", + "includingSystem": "Including system" + }, + "filters": { + "title": "Filters", + "clear": "Clear", + "last24h": "Last 24h", + "failuresOnly": "Failures only", + "authEvents": "Auth events", + "actionPrefix": "Action prefix", + "actionPlaceholder": "e.g. auth., user.update", + "status": "Status", + "any": "Any", + "resourceType": "Resource type", + "resourceTypePlaceholder": "user, alert…", + "resourceId": "Resource id", + "user": "User", + "userPlaceholder": "login…" + }, + "statusValue": { + "success": "Success", + "failure": "Failure" + }, + "table": { + "timestamp": "Timestamp", + "actor": "Actor", + "action": "Action", + "resource": "Resource", + "status": "Status", + "ip": "IP", + "loading": "Loading…", + "emptyTitle": "No audit entries match these filters.", + "emptyHint": "Try clearing filters or widening the date range.", + "system": "system", + "view": "View" + }, + "drawer": { + "entry": "entry #{{id}}", + "overview": "Overview", + "raw": "Raw JSON", + "error": "Error", + "actor": "Actor", + "resource": "Resource", + "ip": "IP", + "userAgent": "User agent", + "session": "Session", + "metadata": "Metadata", + "copy": "Copy", + "copied": "Copied", + "copyJson": "Copy JSON" + } }, - "compliance": "Compliance", - "configure": "Configure", - "dataSources": "Data Sources", - "integrations": "Integrations", - "alertingRules": "Alerting Rules", - "dataProcessing": "Data Processing", - "team": "Team", - "settings": "Settings", - "back": "Back", - "parsingFilters": "Pipelines", - "regexPatterns": "Regex Patterns", - "overview": "Overview", - "tenants": "Tenants", - "liveOps": "Live Operations" - }, - "dashboards": { - "title": "Dashboards", - "subtitle": "Browse and edit interactive dashboards.", - "list": { - "title": "Dashboards", - "create": "New", - "searchPlaceholder": "Search dashboards…", - "loading": "Loading dashboards…", - "empty": "No dashboards yet.", - "rename": "Rename", - "delete": "Delete" + "team": { + "title": "Team", + "subtitle": "Manage users and their roles.", + "tabs": { + "members": "Members", + "roles": "Roles & permissions" + }, + "toast": { + "rolesLoadFailed": "Could not load roles", + "userLoadFailed": "Could not load user", + "rolesUpdated": "Roles updated", + "userReactivated": "User reactivated", + "userDeactivated": "User deactivated", + "tfaReset": "Two-factor authentication reset", + "invitationSent": "Invitation sent", + "loginOrEmailInUse": "That login or email is already in use", + "invalidRequest": "Invalid request", + "noPermission": "You do not have permission to do that", + "userNotFound": "User not found", + "operationFailed": "Operation failed", + "emailInUse": "That email is already in use", + "roleCreated": "Role created", + "roleUpdated": "Role updated", + "roleDeleted": "Role deleted", + "roleNameInUse": "A role with that identifier already exists", + "roleImmutable": "System roles cannot be modified", + "permissionsLoadFailed": "Could not load permissions", + "localUserCreated": "Local user created" + }, + "members": { + "searchPlaceholder": "Search by name or email…", + "invite": "Invite user", + "colUser": "User", + "colRoles": "Roles", + "col2fa": "2FA", + "colStatus": "Status", + "loading": "Loading users…", + "loadFailed": "Could not load users.", + "retry": "Retry", + "noSearchMatch": "No users match your search.", + "none": "No users yet.", + "noRole": "none", + "on": "On", + "off": "Off", + "countLabel_one": "{{count}} user · page {{page}} of {{pages}}", + "countLabel_other": "{{count}} users · page {{page}} of {{pages}}", + "federated": "SSO" + }, + "status": { + "inactive": "Inactive", + "pendingPassword": "Pending password", + "active": "Active", + "pending": "Pending invite", + "suspended": "Suspended" + }, + "drawer": { + "createdBy": "created by {{actor}}", + "loading": "Loading…", + "profileTitle": "Profile", + "profileSubtitle": "Only the user can edit these — from their own profile.", + "name": "Name", + "username": "Username", + "email": "Email", + "language": "Language", + "accountTitle": "Account", + "status": "Status", + "statusActive": "Active", + "statusInactive": "Inactive", + "tfa": "2FA", + "tfaEnabled": "Enabled", + "tfaNotConfigured": "Not configured", + "resetTfa": "Reset", + "resetTfaHint": "Disable this user's 2FA so they can re-enroll at next login", + "resetTfaConfirmTitle": "Reset two-factor authentication?", + "resetTfaConfirmBody": "This disables 2FA for {{name}}. They'll sign in with just their password and can set it up again from their profile.", + "resetTfaConfirm": "Reset 2FA", + "pendingPasswordNote": "Still using the temporary password (invite not completed).", + "lastModified": "Last modified {{time}}", + "rolesTitle": "Roles", + "rolesSubtitle": "Roles grant module permissions. A user can hold more than one.", + "noRoleWarning": "No role assigned — the user will have no module access.", + "deactivate": "Deactivate", + "reactivate": "Reactivate", + "waitingInvite": "Waiting for the user to accept the invitation.", + "cancel": "Cancel", + "saving": "Saving…", + "saveRoles": "Save roles", + "created": "created {{time}}", + "pendingNote": "Invitation not accepted yet.", + "federatedNote": "Signs in through an identity provider." + }, + "invite": { + "title": "Invite user", + "description": "The account is created inactive. The user receives an email to set their password and activate it.", + "username": "Username", + "usernameHint": "At least 3 characters.", + "email": "Email", + "firstName": "First name", + "lastName": "Last name", + "roles": "Roles", + "cancel": "Cancel", + "sending": "Sending…", + "send": "Send invite", + "name": "Name", + "emailHint": "This is the address they sign in with.", + "localDescription": "The account is created with a password and activated immediately. No email is sent.", + "modeInvite": "Invite user", + "modeLocal": "Create local user", + "passwordLabel": "Password", + "passwordPlaceholder": "Set a strong password", + "localUserNote": "This user will not receive an email and will be automatically activated.", + "createLocal": "Create user", + "passwordRules": { + "length": "At least 8 characters", + "case": "At least one uppercase and one lowercase letter", + "special": "At least one special character" + }, + "emailInvalid": "Please enter a valid email address" + }, + "rolePicker": { + "none": "No roles available." + }, + "roles": { + "loading": "Loading roles…", + "loadFailed": "Could not load role permissions.", + "readonlyNote": "Roles and their permissions are defined by the system and are read-only. Assign them to users from the Members tab.", + "permissionsCount_one": "{{count}} permission", + "permissionsCount_other": "{{count}} permissions", + "modulesCount_one": "{{count}} module", + "modulesCount_other": "{{count}} modules", + "matrixTitle": "Permission matrix", + "matrixSubtitle": "What each role can do, by module.", + "permission": "Permission", + "systemNote": "System roles ship with the platform and cannot be edited. Roles you create belong to this tenant.", + "newRole": "New role", + "edit": "Edit", + "delete": "Delete", + "systemBadge": "System", + "createTitle": "New role", + "editTitle": "Edit role", + "editorSubtitle": "Pick what this role may do. A user can hold more than one role.", + "nameLabel": "Identifier", + "nameHint": "Used in code and in the API. ROLE_AUDITOR, for example.", + "displayNameLabel": "Display name", + "descriptionLabel": "Description", + "permissionsLabel": "Permissions", + "selectedCount": "{{count}} selected", + "toggleAll": "all", + "loadingPermissions": "Loading permissions…", + "save": "Save role", + "deleteConfirmTitle": "Delete this role?", + "deleteConfirmBody": "{{name}} will be removed. Users who hold only this role will be left without module access." + }, + "langDefault": "System default", + "relative": { + "justNow": "just now", + "minutesAgo": "{{count}}m ago", + "hoursAgo": "{{count}}h ago", + "daysAgo": "{{count}}d ago" + }, + "roleNames": { + "ROLE_ADMIN": "Administrator", + "ROLE_USER": "User" + }, + "roleDescriptions": { + "ROLE_ADMIN": "Full access to all resources", + "ROLE_USER": "Standard user with module-level read access" + }, + "actions": { + "read": "Read", + "write": "Write", + "delete": "Delete" + }, + "resources": { + "adaudit": "AD Audit", + "alerts": "Alerts", + "audit": "Audit log", + "compliance": "Compliance", + "config": "Configuration", + "dashboards": "Dashboards", + "datasources": "Datasources", + "eventprocessing": "Event processing", + "idp": "Identity providers", + "incidents": "Incidents", + "integrations": "Integrations", + "loganalyzer": "Log analyzer", + "opensearch": "OpenSearch", + "roles": "Roles", + "soar": "SOAR", + "users": "Users", + "notifications": "Notifications", + "socai": "SOC AI", + "tenant": "Tenants", + "threatintel": "Threat intelligence" + } }, - "actions": { - "edit": "Edit", - "editWithAi": "Edit with AI" + "apiKeys": { + "title": "API keys", + "subtitle": "Programmatic access tokens for the UTMStack API.", + "new": "New API key", + "searchPlaceholder": "Search by name or allowed IP…", + "refresh": "Refresh", + "loading": "Loading API keys…", + "loadFailed": "Could not load API keys.", + "retry": "Retry", + "noSearchMatch": "No API keys match your search.", + "empty": "No API keys yet. Create one to get started.", + "anyIp": "Any IP", + "never": "Never", + "count_one": "{{count}} key · page {{page}} of {{pages}}", + "count_other": "{{count}} keys · page {{page}} of {{pages}}", + "enterprise": { + "title": "API keys are an Enterprise feature", + "body": "Issue, scope and rotate API keys for programmatic access to the UTMStack API. This capability is available on the Enterprise edition.", + "upgrade": "Upgrade to Enterprise", + "manageLicense": "Manage your license" + }, + "col": { + "name": "Name", + "allowedIps": "Allowed IPs", + "created": "Created", + "lastRotated": "Last rotated", + "expires": "Expires", + "status": "Status", + "actions": "Actions" + }, + "status": { + "active": "Active", + "expiring": "Expiring", + "expired": "Expired" + }, + "action": { + "rotate": "Rotate", + "edit": "Edit", + "delete": "Delete" + }, + "dialog": { + "editTitle": "Edit API key", + "newTitle": "New API key", + "name": "Name", + "namePlaceholder": "ci-pipeline", + "allowedIps": "Allowed IPs", + "allowedIpsHint": "Comma-separated. Leave empty to allow any IP.", + "expires": "Expires", + "expiresHint": "Leave empty for a key that never expires.", + "secretNote": "The secret token is shown once, right after creation. Copy it then — it can’t be retrieved later (only rotated).", + "cancel": "Cancel", + "saving": "Saving…", + "saveChanges": "Save changes", + "createKey": "Create key" + }, + "confirm": { + "deleteTitle": "Delete API key", + "rotateTitle": "Rotate API key", + "deleteBody": "Delete {{name}}? Any client using it will immediately lose access. This cannot be undone.", + "rotateBody": "Rotate {{name}}? A new secret is issued and the current one stops working immediately. The new token is shown once.", + "cancel": "Cancel", + "working": "Working…", + "delete": "Delete", + "rotate": "Rotate" + }, + "reveal": { + "title": "API key created", + "note": "Copy this secret now — for {{name}}. It won’t be shown again. If you lose it, rotate the key.", + "copied": "Copied", + "copy": "Copy", + "done": "Done" + }, + "toast": { + "updated": "API key updated", + "secretIssueFailed": "Key created, but the secret could not be issued. Use Rotate to get one.", + "deleted": "API key deleted" + }, + "error": { + "nameTaken": "An API key with that name already exists", + "enterpriseRequired": "API keys require the Enterprise edition", + "notFound": "API key not found", + "invalidRequest": "Invalid request", + "failed": "Operation failed" + } }, - "refresh": { - "title": "Auto refresh", - "options": { - "off": "Off", - "10s": "10s", - "30s": "30s", - "1m": "1m", - "5m": "5m", - "15m": "15m" - } + "idp": { + "title": "Identity Providers", + "subtitle": "SAML 2.0 single sign-on for your organization.", + "add": "Add provider", + "enterprise": { + "title": "SSO is an Enterprise feature", + "body": "Connect a SAML 2.0 identity provider (Entra ID, Okta, Google Workspace…) so your team signs in with your IdP. Single sign-on is available on the Enterprise edition.", + "upgrade": "Upgrade to Enterprise" + }, + "loading": "Loading identity providers…", + "loadFailed": "Could not load identity providers.", + "retry": "Retry", + "empty": { + "title": "No identity providers configured", + "body": "Add a SAML 2.0 provider to let your team sign in with your corporate IdP." + }, + "card": { + "enable": "Enable", + "disable": "Disable", + "active": "Active", + "disabled": "Disabled", + "metadataUrl": "Metadata URL", + "spEntityId": "SP Entity ID", + "spAcsUrl": "SP ACS URL", + "loginUrl": "Login URL", + "copy": "Copy", + "edit": "Edit", + "delete": "Delete", + "jit": "Provisioning", + "jitOn": "creates accounts on first sign-in", + "sync": "Roles", + "syncOn": "re-applied on every sign-in" + }, + "form": { + "addTitle": "Add identity provider", + "editTitle": "Edit identity provider", + "name": "Name", + "nameHint": "Unique. Used in the SSO URL.", + "providerType": "Provider type", + "providerTypeHint": "A label, e.g. azure, okta, google.", + "metadataUrl": "IdP metadata URL", + "spEntityId": "SP Entity ID", + "spAcsUrl": "SP ACS URL", + "certificate": "SP certificate (PEM)", + "privateKey": "SP private key (PEM)", + "privateKeyHintEdit": "Leave empty to keep the stored key.", + "privateKeyHintCreate": "Required. Stored encrypted; never shown again.", + "privateKeyUnchanged": "•••••••• (unchanged)", + "active": "Active (show on the login page)", + "cancel": "Cancel", + "saving": "Saving…", + "save": "Save changes", + "create": "Create provider", + "issuer": "Issuer URL", + "issuerHint": "Discovery runs against this; the provider must serve /.well-known/openid-configuration under it.", + "clientId": "Client ID", + "redirectUrl": "Redirect URL", + "redirectUrlHint": "Register this exact URL with the provider.", + "host": "Host", + "port": "Port", + "startTls": "TLS", + "startTlsOn": "Use StartTLS", + "bindDn": "Bind DN", + "bindDnHint": "A service account that may search the directory.", + "baseDn": "Base DN", + "userFilter": "User filter", + "userFilterHint": "Must contain %s, where the address typed at login is placed.", + "emailAttribute": "Email attribute", + "nameAttribute": "Name attribute", + "groupAttribute": "Group attribute", + "provisioning": "Accounts and roles", + "provisioningHint": "What happens when someone the directory vouches for signs in.", + "jit": "Create the account on first sign-in", + "defaultRole": "Default role", + "defaultRoleHint": "Given when no group matches. Without one, an unmatched sign-in is refused.", + "noDefaultRole": "None", + "groupsAttribute": "Groups attribute", + "groupsAttributeHint": "Where the provider puts group membership.", + "syncRoles": "Re-apply roles on every sign-in", + "syncRolesHint": "Roles not in the mapping are removed, so a change in the directory reaches here. Without this, a demotion never arrives.", + "mappings": "Group to role", + "mappingsHint": "A directory group on the left, the role it grants on the right.", + "addMapping": "Add", + "noMappings": "No mappings. Everyone gets the default role.", + "groupPlaceholder": "SOC Analysts", + "pickRole": "Pick a role", + "secret.saml": "SP private key", + "secret.oidc": "Client secret", + "secret.ldap": "Bind password", + "secretHintCreate": "Stored encrypted and never shown again.", + "secretHintEdit": "Leave blank to keep the stored one.", + "secretUnchanged": "unchanged", + "errors": { + "required": "This field is required.", + "url": "Must be a valid http(s) URL.", + "httpsUrl": "Must be a valid https URL.", + "hostname": "Enter a host or IP without a scheme (e.g. ldap.example.com).", + "port": "Port must be a whole number between 0 and 65535.", + "pemCertificate": "Does not look like a PEM certificate (missing -----BEGIN/END CERTIFICATE-----).", + "pemKey": "Does not look like a PEM private key (missing -----BEGIN/END PRIVATE KEY-----).", + "userFilterPlaceholder": "The filter must contain %s, where the login address is placed.", + "userFilterUnbalanced": "Parentheses are unbalanced — the search will return nothing.", + "nameFormat": "Use letters, digits, dots, dashes or underscores (max 64). It appears in the SSO URL, so no spaces.", + "redirectUrl": "Must be a valid https URL, or an http loopback URL (localhost / 127.0.0.1 / [::1]).", + "entityId": "Must be a valid URI, e.g. https://utmstack.example.com/sp." + } + }, + "delete": { + "title": "Delete identity provider", + "body": "Delete {{name}}? Users will no longer be able to sign in through it. This cannot be undone.", + "cancel": "Cancel", + "deleting": "Deleting…", + "confirm": "Delete" + }, + "toast": { + "enabled": "Provider enabled", + "disabled": "Provider disabled", + "created": "Identity provider created", + "updated": "Identity provider updated", + "deleted": "Identity provider deleted", + "paidPlan": "SAML SSO requires a paid plan", + "enterpriseRequired": "SSO requires the Enterprise edition", + "notFound": "Identity provider not found", + "invalid": "Invalid configuration", + "failed": "Operation failed" + }, + "providerType": { + "saml": "SAML 2.0", + "oidc": "OpenID Connect", + "ldap": "LDAP / Active Directory", + "comingSoon": "not available yet" + } }, - "editor": { - "editing": "Editing", - "addWidget": "Add widget", - "editFilters": "Edit filters", - "save": "Save", - "discard": "Discard", - "newTitle": "New widget", - "newSubtitle": "Pick a chart type, choose a data source, and shape it visually. SQL is generated for you.", - "editTitle": "Edit widget", - "editSubtitle": "Tweak the chart definition. Changes apply everywhere this widget is used.", - "loading": "Loading widget…", - "notFoundTitle": "Widget not found", - "notFoundSubtitle": "It may have been deleted or you may not have access.", - "backToDashboard": "Back to dashboard", - "chartType": { - "title": "Chart type" - }, - "chartTypes": { - "bar": { - "label": "Bar", - "description": "Compare values across categories." - }, - "line": { - "label": "Line", - "description": "Trends over an ordered axis." - }, - "area": { - "label": "Area", - "description": "Filled line — emphasises volume." - }, - "pie": { - "label": "Pie", - "description": "Share of a whole by category." - }, - "metric": { - "label": "Metric", - "description": "A single scalar value." + "userAuditor": { + "title": "User auditor", + "subtitle": "Active Directory accounts observed in your Windows security logs — discovered from create, logon and delete events.", + "export": "Export", + "accountsChip": "{{count}} accounts", + "overview": { + "title": "Account inventory", + "active": "active", + "disabled": "disabled", + "deleted": "deleted", + "seen24h": "{{count}} seen in the last 24 hours", + "byDomain": "By domain", + "grouped": "{{count}} grouped", + "unassigned": "{{count}} unassigned" }, - "table": { - "label": "Table", - "description": "Aggregated rows." + "views": { + "all": "All accounts", + "windows": "Windows", + "linux": "Linux", + "active": "Active", + "disabled": "Disabled", + "deleted": "Deleted", + "service": "Service accounts", + "stale": "Stale (30d+)", + "o365": "O365", + "azure": "Azure", + "gcp": "GCP", + "aws": "AWS" + }, + "searchPlaceholder": "Search by account name or SID…", + "allTenants": "All tenants", + "filters": { + "add": "Add filter", + "clearAll": "Clear all", + "filterValues": "Filter values…", + "loadingValues": "Loading values…", + "noValues": "No values found.", + "pickValue": "Pick a value to add the filter.", + "empty": "(empty)", + "cancel": "Cancel", + "addBtn": "Add" + }, + "filterFields": { + "status": "Lifecycle status" + }, + "ops": { + "is": "is" + }, + "refresh": "Refresh", + "layout": { + "list": "List", + "cards": "Cards" }, "list": { - "label": "List", - "description": "Raw, non-aggregated rows." + "account": "Account", + "identity": "Identity", + "sid": "SID", + "status": "Status", + "lastLogon": "Last logon", + "lastSeen": "Last seen", + "tenant": "Tenant", + "accountId": "Account ID", + "identityGroup": "Identity group" + }, + "status": { + "active": "Active", + "disabled": "Disabled", + "deleted": "Deleted" + }, + "badge": { + "service": "service", + "stale": "stale" + }, + "empty": "No accounts match this view.", + "loadError": "Could not load AD accounts.", + "retry": "Retry", + "card": { + "lastLogon": "Last logon" + }, + "pageInfo": "{{from}}–{{to}} of {{count}}", + "drawer": { + "tenantInline": "tenant {{id}}", + "serviceAccount": "service account", + "stale": "stale 30d+", + "viewInLogs": "View events in Log Explorer", + "copySid": "Copy SID", + "copyUid": "Copy identity", + "copied": "Copied", + "identity": "Identity", + "accountName": "Account name", + "domain": "Domain", + "hostname": "Hostname", + "sid": "SID", + "uidNumber": "UID", + "machineId": "Machine ID", + "tenant": "Tenant", + "adStatus": "AD status", + "enabled": "Enabled", + "disabled": "Disabled", + "lifecycle": "Lifecycle", + "created": "Account created", + "lastLogon": "Last logon", + "lastSeen": "Last seen in logs", + "deleted": "Account deleted", + "noLifecycle": "No lifecycle events recorded.", + "aliasGroup": "Identity group", + "alias": { + "add": "Add identity group", + "search": "Search groups…", + "none": "No groups yet", + "new": "New group", + "unassign": "Remove from group", + "unassigned": "No group", + "newPlaceholder": "New group name (2–64 chars)", + "createAndAssign": "Create & assign", + "nameTooShort": "Group name must be 2–64 characters", + "updated": "Identity group updated", + "updateFailed": "Could not update the identity group" + } + }, + "relative": { + "justNow": "just now", + "minutesAgo": "{{count}}m ago", + "hoursAgo": "{{count}}h ago", + "daysAgo": "{{count}}d ago" + }, + "none": "—", + "allIdentities": "All identity groups", + "noneIdentity": "No identity group" + }, + "connectionKey": { + "title": "Connection key", + "subtitle1": "The key agents present when they register with this instance.", + "subtitleEmphasis": "It is only used for agent installation", + "subtitle2": "— not for collectors, integrations, or the API. It is managed by the agent-manager.", + "status": { + "label": "Status", + "loading": "Loading…", + "unavailable": "Agent-manager unavailable", + "active": "Active", + "unavailableHint": "Could not reach the agent-manager to read the key.", + "activeHint": "Agents can register using this key." + }, + "token": { + "title": "Connection key", + "subtitle": "Treat this value as a credential. Rotating it issues a new key for future agent installations — agents already registered keep working.", + "loadFailedTitle": "Couldn’t load the connection key", + "unavailableTitle": "Connection key unavailable", + "loadFailedHint": "The key is managed by the agent-manager, which didn’t respond. Try again in a moment.", + "retry": "Retry", + "show": "Show key", + "hide": "Hide key", + "copy": "Copy", + "copied": "Copied", + "regenerate": "Regenerate connection key", + "confirmTitle": "Regenerate the key?", + "confirmBody": "New agent installations will need the new key. Agents already registered keep working. There's no undo.", + "regenerating": "Regenerating…", + "confirmYes": "Yes, regenerate", + "cancel": "Cancel" }, - "region_map": { - "label": "Coordinate map", - "description": "Plot markers on a world map using lat/lon coordinates." + "security": { + "title": "Security recommendations", + "subtitle": "Best practices for protecting this credential.", + "rotateTitle": "Rotate every 90 days", + "rotateBody": "Schedule a recurring rotation. UTMStack can email you a reminder when the key is older than 90 days.", + "rotateAction": "Set up reminder", + "secretTitle": "Store as a secret", + "secretBody": "Don't commit the key to source control. Use your secret manager (Vault, AWS SM, etc.) and inject it at install time.", + "auditTitle": "Audit who fetched it", + "auditBody": "Every fetch and rotation is recorded in the application audit log.", + "auditAction": "View audit log" }, - "text": { - "label": "Text", - "description": "Free-form text or plain row output." + "toast": { + "loadFailed": "Could not load connection key", + "rotated": "Connection key rotated", + "rotateFailed": "Could not rotate connection key", + "copyFailed": "Could not copy" } - }, - "dataSource": { - "title": "Which data?", - "dataset": "Data set", - "noDatasetHint": "Choose a data set to enable conditions and grouping." - }, - "widgetTitle": { - "label": "Title", - "placeholder": "Optional — defaults to the chart type" - }, - "dataset": { - "placeholder": "Select a data set…", - "loading": "Loading data sets…" - }, - "filters": { - "title": "Include only events where…", - "empty": "No conditions — all events in the time range are included.", - "add": "Add condition", - "remove": "Remove", - "field": "Field", - "fieldPlaceholder": "e.g. host.name", - "operator": "Operator", - "value": "Value", - "valuePlaceholder": "Value", - "from": "From", - "to": "To", - "noValue": "No value needed", - "listPlaceholder": "Comma-separated values" - }, - "operators": { - "IS": "is", - "IS_NOT": "is not", - "IS_ONE_OF_TERMS": "is one of", - "IS_GREATER_THAN": "is greater than", - "IS_LESS_THAN_OR_EQUALS": "is less than or equals", - "IS_BETWEEN": "is between", - "CONTAIN": "contains", - "DOES_NOT_CONTAIN": "does not contain", - "START_WITH": "starts with", - "ENDS_WITH": "ends with", - "EXIST": "exists", - "DOES_NOT_EXIST": "does not exist" - }, - "dimension": { - "title": "Group by", - "field": "Field", - "placeholder": "Pick a field to group by…" - }, - "table": { - "hint": "Shows every field the records carry. Add columns to pick specific ones.", - "columnsTitle": "Columns", - "allColumns": "All columns will be shown. Add fields to pick specific ones.", - "addColumn": "Add a column…", - "removeColumn": "Remove column" - }, - "chartPreview": { - "title": "Chart preview", - "noQuery": "Pick a data set to see a preview.", - "error": "Preview query failed." - }, - "chartTypeChip": { - "label": "Chart:" - }, - "chartTypeModal": { - "title": "Pick a chart type", - "subtitle": "Choose how to visualize the data. You can change this later.", - "confirm": "Continue", - "swapTitle": "Change chart type", - "swapConfirm": "Apply" - }, - "saveVisualization": "Save widget", - "fieldSelect": { - "loading": "Loading fields…", - "choose": "Choose a field…" - }, - "toast": { - "notReady": "Pick a data set, and a field to break down by, before saving." - }, - "breakdown": { - "title": "Break down by", - "topValuesTable": "Top values table", - "time": "Over time", - "field": "Top values", - "interval": "Bucket size", - "intervalAuto": "Auto", - "limit": "How many", - "limitPlaceholder": "Default (50)", - "splitHint": "Optional: one line per value of this field." - } - }, - "grid": { - "empty": "This dashboard has no widgets yet.", - "missingVisualization": "Widget unavailable", - "unknownVisualization": "Widget" - }, - "widget": { - "renderError": "Could not render this widget.", - "count": "Count", - "loading": "Loading data…", - "queryError": "Could not load widget data.", - "noData": "No data for the selected time range.", - "regionMapEmpty": "No points with valid lat/lon.", - "regionMapShapeHint": "The SQL must return latitude and longitude columns (or a value array [lat, lon, count]).", - "regionMapUnnamed": "(unnamed)", - "regionMapValue": "value: {{value}}", - "editAriaLabel": "Edit widget", - "removeAriaLabel": "Remove widget", - "moveBack": "Move back", - "moveForward": "Move forward", - "width": "Width", - "height": "Height", - "widthSmall": "1 col", - "widthMedium": "2 cols", - "widthLarge": "3 cols", - "heightNormal": "Normal", - "heightTall": "Tall", - "incompleteSpec": "This widget is missing part of its question." }, - "form": { - "createTitle": "New dashboard", - "renameTitle": "Edit dashboard", - "name": "Name", - "namePlaceholder": "e.g. Network overview", - "description": "Description", - "descriptionPlaceholder": "Optional", - "cancel": "Cancel", - "create": "Create", - "save": "Save" - }, - "confirm": { - "deleteTitle": "Delete dashboard", - "delete": "Delete dashboard \"{{name}}\"? This cannot be undone.", - "deleteWidgetsTitle": "Delete widgets", - "deleteWidgets_one": "Delete this widget? This cannot be undone.", - "deleteWidgets_other": "Delete {{count}} widgets? This cannot be undone.", - "dismissTitle": "Remove dashboard", - "dismiss": "Remove the default dashboard \"{{name}}\"? You can start a new one from it later — \"New\" → \"From an existing one\"." - }, - "page": { - "noSelection": "Pick a dashboard from the list, or create one to get started.", - "loading": "Loading widgets…" - }, - "toast": { - "created": "Dashboard created.", - "createFailed": "Could not create dashboard.", - "updated": "Dashboard updated.", - "updateFailed": "Could not update dashboard.", - "deleted": "Dashboard deleted.", - "deleteFailed": "Could not delete dashboard.", - "layoutSaved": "Layout saved.", - "layoutSaveFailed": "Could not save layout.", - "visualizationCreated": "Widget created.", - "visualizationCreateFailed": "Could not create widget.", - "visualizationUpdated": "Widget updated.", - "visualizationUpdateFailed": "Could not update widget.", - "visualizationDeleted": "Widget deleted.", - "visualizationDeleteFailed": "Could not delete widget.", - "filtersSaved": "Filters saved.", - "filtersSaveFailed": "Could not save filters.", - "filterCreated": "Filter created.", - "filterUpdated": "Filter updated.", - "filterDeleted": "Filter deleted.", - "filterCreateFailed": "Could not create filter.", - "filterUpdateFailed": "Could not update filter.", - "filterDeleteFailed": "Could not delete filter." - }, - "filters": { - "chooseValue": "Choose…", - "selected": "selected", - "loading": "Loading values…", - "searchPlaceholder": "Search values…", - "noValues": "No values available.", - "loadError": "Could not load values.", - "clear": "Clear", - "editorTitle": "Dashboard filters", - "editorHint": "Add dropdown chips that filter every widget on this dashboard.", - "emptyEditor": "No filter chips yet. Add one to get started.", - "addChip": "Add filter", - "cancel": "Cancel", - "save": "Save", - "field": { - "dataset": "Data set", - "field": "Field", - "chooseField": "Choose a field…", - "label": "Label", - "labelPlaceholder": "e.g. Host", - "placeholder": "Placeholder", - "placeholderPlaceholder": "e.g. Pick a host", - "multiple": "Multiple", - "searchable": "Searchable" - }, - "addTitle": "Add filter", - "editTitle": "Edit filter", - "removeTitle": "Remove filter", - "removeConfirm": "Remove filter \"{{label}}\"? This cannot be undone.", - "remove": "Remove", - "editAria": "Edit filter", - "removeAria": "Remove filter", - "saving": "Saving…" - }, - "newDashboard": { - "title": "New dashboard", - "subtitle": "Create a blank dashboard. You can add widgets after it's saved.", - "modeManual": "Create manually", - "modeAi": "Using AI", - "aiLocked": "Enable SOC-AI and configure it to use this.", - "aiDescriptionLabel": "What should this dashboard show?", - "aiDescriptionPlaceholder": "e.g. Failed logins by country, last 7 days", - "aiCreate": "Create with AI", - "aiOpenerWithDetails": "Create a dashboard named \"{{name}}\" showing: {{description}}" + "dataRetention": { + "title": "Data retention", + "subtitle": "How long each dataset is kept, and when its records stop costing local disk.", + "loading": "Loading…", + "loadFailed": "Could not read the store.", + "retry": "Retry", + "datasets": { + "logs": "Logs", + "alerts": "Alerts", + "statistics": "Ingestion statistics" + }, + "holding": "{{documents}} records · {{size}}", + "since": "since {{date}}", + "diskUsed": "Disk {{pct}}% used", + "keep": "Delete after", + "keepHint": "A record is deleted this many days after it happened, wherever it is stored by then.", + "cold": "Move to cold storage after", + "coldHint": "Older records move to object storage and stay queryable. 0 keeps everything on local disk.", + "coldUnavailable": "Set up cold storage below to move older records off local disk.", + "coldBeforeDelete": "Records have to move before they are deleted: use fewer days than the lifetime, or 0.", + "tieredNote": "This dataset moves records to cold storage. Going back to local-only needs the table rebuilt, so it cannot be turned off here.", + "days": "days", + "save": "Save", + "saving": "Saving…", + "toast": { + "saved": "Retention saved", + "noPermission": "You do not have permission to change retention", + "saveFailed": "Could not save the retention" + }, + "coldStorage": { + "title": "Cold storage", + "hint": "An object store the event store treats as a second, slower disk. Older records move there and are still queried from the same place — it is not an archive and nothing has to be restored.", + "active": "In use", + "inactive": "Not set up", + "writtenNotReady": "The bucket is configured but the store has not picked it up. Check that the deployment shares the store's configuration directory.", + "endpoint": "Bucket URL", + "accessKey": "Access key", + "secretKey": "Secret key", + "bucketLocked": "The credentials can be changed at any time. The bucket cannot, once records live in it: the parts already moved carry it.", + "enable": "Enable cold storage", + "update": "Update credentials", + "toast": { + "saved": "Cold storage configured", + "failed": "Could not configure cold storage" + }, + "kind": "Type", + "kind_s3": "S3-compatible object store", + "kind_local": "Local folder or NFS", + "kind_azure": "Azure Blob Storage", + "accountUrl": "Storage account URL", + "container": "Container", + "accountName": "Account name", + "accountKey": "Account key", + "useRole": "Use the server's IAM role instead of keys", + "s3Hint": "Works with AWS S3 and any S3-compatible store: MinIO, Ceph, Wasabi, Cloudflare R2, or Google Cloud Storage (endpoint https://storage.googleapis.com// with HMAC keys).", + "localHint": "Records move to the folder mounted at /mnt/utmstack-cold inside the event store: a plain directory in the data folder, or an NFS share mounted over /clickhouse/cold on the host before the stack starts. No credentials needed.", + "changeWarning": "Records already moved to the current destination are not migrated. They stay there and stop being readable from here until the old destination is copied across by hand." + }, + "forbidden": { + "title": "This page belongs to the platform", + "body": "Retention applies to the tables every tenant shares, so only a platform administrator can read or change it. Ask one, or sign in with a platform account." + } }, - "newVisualization": { - "title": "New widget", - "subtitle": "Define a reusable chart from a SQL query and an ECharts option config.", - "sqlQuery": "SQL query", - "sqlQueryPlaceholder": "SELECT bucket, count(*) FROM logs GROUP BY bucket", - "sqlQueryHint": "Use the placeholders timeFilter, from, and to (in double curly braces) so the time picker is applied at render time.", - "config": "Chart config (ECharts option, JSON)", - "configHint": "Must be valid JSON. Rows from the SQL are exposed as `dataset.source` — wire your series with `encode`.", - "configError": "Invalid JSON: {{error}}" + "languageSettings": { + "title": "Platform language", + "subtitle": "Default UI language for pre-login screens, system emails and new users. Each user can still pick their own in their profile.", + "label": "Default language", + "hint": "Used when a user hasn't chosen their own language.", + "save": "Save", + "saving": "Saving…", + "saved": "Platform language updated", + "loadError": "Could not load the language setting", + "saveError": "Could not save the language setting" + }, + "branding": { + "title": "Branding", + "subtitle": "White-label UTMStack with your organization’s identity — applied everywhere: the login screen, sidebar, emails and reports.", + "enterpriseRequired": "White-labeling is an Enterprise feature.", + "manageLicense": "Manage license", + "enable": { + "title": "White-label", + "description": "Replace the UTMStack brand with your own across the platform.", + "label": "Enable white-labeling" + }, + "identity": { + "title": "Identity", + "productName": "Product name", + "productNameHint": "Shown in the title bar, sidebar and emails.", + "accent": "Accent color", + "accentHint": "Primary color for buttons, links and active states.", + "custom": "Custom color" + }, + "logos": { + "title": "Logos", + "hint": "PNG, SVG, WEBP, JPG or ICO. Up to 5 MB.", + "logo": "Logo (light)", + "logoDark": "Logo (dark)", + "favicon": "Favicon" + }, + "reports": { + "title": "Report assets", + "hint": "Embedded in generated PDF reports.", + "reportLogo": "Report logo", + "reportCover": "Report cover" + }, + "asset": { + "upload": "Upload", + "replace": "Replace" + }, + "save": "Save changes", + "saving": "Saving…", + "saved": "Branding updated", + "saveError": "Could not save branding", + "uploaded": "Image uploaded", + "uploadError": "Could not upload image", + "loadError": "Could not load branding", + "enterprise": { + "title": "White-labelling is an Enterprise feature", + "body": "Replace the product name, logo and report cover with your own, so the panel and everything it generates carry your brand instead of UTMStack's.", + "upgrade": "Upgrade to Enterprise" + }, + "restore": "Restore UTMStack defaults", + "restored": "Branding restored to the UTMStack defaults" + }, + "emailConfig": { + "title": "Email configuration", + "subtitle": "SMTP server used to send alert notifications, reports and account emails.", + "server": { + "title": "SMTP server", + "host": "Host", + "hostHint": "Hostname of your SMTP server.", + "port": "Port", + "encryption": "Encryption", + "username": "Username", + "password": "Password", + "passwordSetHint": "A password is saved. Leave blank to keep it, or type a new one to change it." + }, + "encryptionOpt": { + "TLS": "TLS", + "SSL": "SSL", + "NONE": "None" + }, + "sender": { + "title": "Sender", + "from": "From address", + "fromHint": "Address emails are sent from.", + "organization": "Organization name", + "organizationHint": "Shown in alert and incident notification emails.", + "baseUrl": "Base URL", + "baseUrlHint": "Public URL of this instance, used for links in emails." + }, + "test": { + "button": "Send test", + "sending": "Sending…", + "sentTo": "A test email will be sent to {{email}}.", + "success": "Test email sent to {{email}}", + "fail": "Could not send the test email", + "fromRequired": "Set a From address before testing" + }, + "save": "Save changes", + "saving": "Saving…", + "saved": "Email configuration saved", + "saveError": "Could not save the configuration", + "loadError": "Could not load the configuration", + "recipients": { + "alertsTitle": "Alert recipients", + "incidentsTitle": "Incident recipients", + "to": "To", + "cc": "CC", + "alertsHelper": "Addresses notified when new alerts are raised. Leave empty and alerts are not emailed.", + "incidentsHelper": "Addresses notified when an incident is created. Leave empty and incidents are not emailed.", + "add": "Add" + } }, - "visualizationList": { - "title": "Widgets", - "subtitle": "{{count}} widget(s) available.", - "subtitleFiltered": "Showing {{shown}} of {{total}}.", - "create": "New", - "searchPlaceholder": "Search widgets…", - "loading": "Loading widgets…", - "empty": "No widgets yet.", - "emptyFiltered": "No widgets match the current filters.", - "delete": "Delete", - "deleteTitle": "Delete widget", - "confirmDelete": "Delete widget \"{{name}}\"? This cannot be undone.", - "filters": { - "search": "Search", - "chartType": "Chart type", - "allChartTypes": "All chart types", - "source": "Source", - "allSources": "All sources", - "createdAt": "Created", - "modifiedAt": "Modified", - "createdRangeTitle": "Custom range — Created", - "modifiedRangeTitle": "Custom range — Modified", - "pickRange": "Pick a range", - "datePresets": { - "all": "All time", - "today": "Today", - "last7": "Last 7 days", - "last30": "Last 30 days", - "lastYear": "Last year", - "custom": "Custom range" - }, - "clear": "Clear filters" - }, - "col": { - "name": "Name", - "chartType": "Chart type", - "source": "Source", - "description": "Description", - "created": "Created", - "modified": "Modified" - } + "dateFormat": { + "title": "Date & time", + "subtitle": "How timestamps are displayed across the platform. Logs are always stored in UTC.", + "timezone": { + "title": "Time zone", + "hint": "Timestamps are shown in this time zone. Stored data stays in UTC.", + "system": "Browser default", + "now": "Now: {{value}}" + }, + "format": { + "title": "Date format", + "hint": "Style used for dates and times." + }, + "styles": { + "short": "Short", + "medium": "Medium", + "long": "Long", + "full": "Full" + }, + "save": "Save changes", + "saving": "Saving…", + "saved": "Date settings saved", + "saveError": "Could not save the settings", + "loadError": "Could not load the settings" + }, + "about": { + "title": "About this instance", + "subtitle": "Version, license, and system health for this UTMStack deployment.", + "loading": "Loading instance information…", + "edition": { + "enterprise": "Enterprise", + "community": "Community" + }, + "fields": { + "hostname": "Server", + "instanceId": "Instance ID", + "noInstanceMeta": "No instance metadata available." + }, + "license": { + "title": "License", + "enterpriseMssp": "Enterprise · MSSP", + "datasources": "Datasources", + "communityLimited": "Community limit", + "unlimited": "Unlimited", + "expires": "Expires", + "managedNote": "Edition, datasource limits and license upload are managed on the License page.", + "view": "View license", + "ingest": "Ingest volume", + "notMetered": "Not metered", + "gbPerMonth": "{{gb}} GB/month" + }, + "services": { + "backend": { + "name": "Backend API", + "desc": "REST gateway, auth and module orchestration." + }, + "opensearch": { + "name": "OpenSearch", + "desc": "Log and event storage backend.", + "detail": "{{nodes}} nodes · {{shards}} shards" + }, + "unreachable": "Unreachable" + }, + "status": { + "up": "Healthy", + "degraded": "Degraded", + "down": "Down", + "unknown": "Unknown" + }, + "health": { + "title": "System health", + "allHealthy": "All services healthy. Refresh to recheck.", + "issues_one": "{{count}} service needs attention.", + "issues_other": "{{count}} services need attention.", + "refresh": "Refresh" + }, + "usage": { + "title": "Data sources", + "subtitle": "Data sources configured in this deployment.", + "ofUnlimited": "of unlimited", + "ofLimit": "of {{limit}}", + "overLimit": "Over the licensed limit — data beyond the cap is at risk.", + "configured": "configured" + }, + "support": { + "title": "Support", + "docs": "Documentation", + "repo": "GitHub repository", + "issues": "Report an issue", + "website": "utmstack.com" + }, + "legal": { + "title": "Legal", + "license": "License", + "security": "Security disclosure", + "copyright": "© {{year}} UTMStack. All rights reserved." + } }, - "tabs": { - "dashboards": "Dashboards", - "visualizations": "Widgets", - "newDashboard": "New dashboard", - "unsetDefault": "Unset default", - "options": "Options" + "logExplorer": { + "title": "Log explorer", + "eventsIn": "events in", + "searching": "Searching…", + "query": { + "allDataTypes": "All data types", + "dataTypes": "Data types", + "exportCsv": "Export CSV", + "filterDataTypes": "Filter data types…", + "noDataTypes": "No data types", + "noDataTypesMatch": "No matching data types", + "noTextSearch": "This data source has no full-text field — filter by field instead", + "refresh": "Refresh", + "run": "Run", + "search": "Search", + "searchPlaceholder": "Search across all fields…" + }, + "time": { + "15m": "Last 15 minutes", + "1h": "Last 1 hour", + "6h": "Last 6 hours", + "24h": "Last 24 hours", + "7d": "Last 7 days", + "30d": "Last 30 days" + }, + "ops": { + "is": "is", + "isNot": "is not", + "contains": "contains", + "exists": "exists", + "between": "between", + "search": "search", + "isOneOf": "is one of", + "isNotOneOf": "is not one of", + "doesNotContain": "does not contain", + "startsWith": "starts with", + "doesNotStartWith": "does not start with", + "endsWith": "ends with", + "doesNotEndWith": "does not end with", + "doesNotExist": "does not exist", + "notBetween": "not between", + "greaterThan": "is greater than", + "greaterThanOrEquals": "is greater than or equal to", + "lessThan": "is less than", + "lessThanOrEquals": "is less than or equal to" + }, + "filters": { + "label": "Filters", + "clearAll": "Clear all" + }, + "fields": { + "title": "Fields", + "filterPlaceholder": "Filter fields…", + "none": "No fields", + "selected": "Selected fields", + "available": "Available fields", + "topValues_one": "Top {{count}} value", + "topValues_other": "Top {{count}} values", + "loading": "Loading…", + "noValues": "No values", + "addColumn": "Add as column", + "removeColumn": "Remove column from table", + "filterFor": "Filter for value", + "filterOut": "Filter out value", + "empty": "(empty)" + }, + "results": { + "dataTypesFailed": "Could not load data types.", + "endOfResults": "All {{count}} events loaded", + "loadingMore": "Loading more…", + "message": "Message", + "none": "No logs match this query.", + "removeColumn": "Remove {{field}}", + "retry": "Retry", + "searchFailed": "Search failed.", + "searching": "Searching…", + "source": "Source", + "time": "Time", + "scope": "Searched {{dataset}} · {{dataType}}.", + "searchAllDataTypes": "Search every data type" + }, + "detail": { + "fieldsCount_one": "{{count}} field", + "fieldsCount_other": "{{count}} fields", + "copyJson": "Copy JSON", + "copied": "Document copied", + "parsedFields": "Parsed fields", + "json": "JSON", + "filterFor": "Filter for", + "filterOut": "Filter out", + "surrounding": "Surrounding events", + "surroundingHint": "Show events ±15 min around this one, from the same source" + }, + "view": { + "table": "Table", + "chart": "Chart" + }, + "chart": { + "aggregateOn": "Aggregate on", + "per": "per", + "topValues": "— top 20 values", + "building": "Building chart…", + "failed": "Could not build the chart for this field.", + "noData": "No data to chart." + }, + "intervals": { + "minute": "Minute", + "hour": "Hour", + "day": "Day", + "week": "Week", + "month": "Month", + "quarter": "Quarter", + "year": "Year" + }, + "toast": { + "exportFailed": "Export failed" + }, + "builder": { + "add": "Add filter", + "filterValues": "Filter values…", + "loadingValues": "Loading values…", + "noValues": "No values found.", + "pickValue": "Pick a value to add the filter.", + "cancel": "Cancel", + "confirm": "Add" + }, + "related": { + "nLogs_one": "{{count}} log", + "nLogs_other": "{{count}} logs", + "truncated": "Showing the first {{count}} related logs (the full set is larger)." + }, + "saved": { + "title": "Saved", + "empty": "No saved searches yet", + "saveCurrent": "Save current search", + "save": "Save", + "namePlaceholder": "Search name", + "delete": "Delete", + "saved": "Saved “{{name}}”", + "loading": "Loading…", + "loadFailed": "Could not load saved searches", + "saveFailed": "Could not save the search", + "deleteFailed": "Could not delete the search", + "unreadable": "That saved search could not be read" + } }, - "picker": { - "none": "Select dashboard", - "search": "Search dashboards…", - "new": "New dashboard", - "setDefault": "Set as default", - "empty": "No dashboards" + "integrations": { + "title": "Integrations", + "searchPlaceholder": "Search integrations…", + "noMatch": "No integrations match.", + "browseMarketplace": "Browse marketplace", + "loading": "Loading integrations…", + "addCustom": { + "title": "Add custom integration", + "description": "Create a new custom source", + "cta": "Create" + }, + "tabs": { + "all": "All", + "agents": "Agents", + "collectors": "Collectors", + "cloud": "Cloud", + "custom": "Custom" + }, + "kind": { + "agents & syslog": "Agent", + "device": "Collector", + "antivirus": "Collector", + "other": "Collector", + "custom": "Custom", + "cloud": "Cloud", + "utmstack modules": "Collector" + }, + "status": { + "configured": "Configured", + "available": "Available" + }, + "card": { + "manage": "Manage →", + "setup": "Set up →", + "eventsPerSec": "{{rate}} e/s", + "enabled": "Enabled", + "setupShort": "Set up" + }, + "drawer": { + "manage": "Manage", + "openDashboard": "Open dashboard", + "viewEvents": "View events", + "documentation": "Documentation", + "getInstallCmd": "Get install command", + "setupCollector": "Set up collector", + "connect": "Connect", + "configureCustom": "Configure custom source", + "eventsRate": "{{rate}} events/sec · {{count}} in 24h", + "manageRules": "Rules", + "manageFilters": "Filters" + }, + "setup": { + "agent": { + "howItWorksTitle": "How it works", + "howItWorksBody": "The {{name}} agent is a small daemon that runs on the host and forwards local events to UTMStack over an authenticated TLS connection. It auto-updates and reports its health.", + "installTitle": "Install on {{name}}", + "installHint": "Run this command on every {{name}} host you want to monitor. The token already encodes your current workspace.", + "afterTitle": "What you'll see after install", + "after1": "The host appears under Data Sources within ~60 seconds of agent start.", + "after2": "Telemetry begins flowing into Log Explorer, scoped to your workspace.", + "after3": "The agent self-reports CPU / memory / disk health back to UTMStack.", + "actionLabel": "Action", + "platformLabel": "Platform", + "optionsLabel": "Options", + "skipCertValidation": "Skip TLS certificate validation (self-signed server)", + "noRemoteControl": "Disable remote command execution on this host", + "loadingToken": "Loading token…", + "actions": { + "install": "Install", + "uninstall": "Uninstall" + }, + "prereqTitle": "Pre-installation requirements", + "prereqBody": "The UTMStack agent communicates with the server over the following ports. Make sure they are open between the host and UTMStack before installing:", + "sensitiveWarning": "The command below contains a sensitive enrollment token — do not share it.", + "uninstall": { + "title": "Uninstall the agent", + "body": "Run this on the host to stop and remove the UTMStack agent and its services. It uses the platform selected above." + }, + "macCompat": "Requires macOS 11 (Big Sur) or later on Apple Silicon (M1/M2/M3 or newer). Intel-based Macs are not supported." + }, + "collector": { + "howItWorksTitle": "How it works", + "howItWorksBody": "{{name}} doesn't run a UTMStack agent. Instead, you install the UTMStack collector somewhere on the network that both your {{name}} device and UTMStack can reach. {{name}} sends syslog to the collector, the collector parses, normalizes, and forwards events into UTMStack.", + "step1Title": "1 · Install the UTMStack collector", + "step1Hint": "Run on a Linux host with network access from the {{name}} device.", + "step2Title": "2 · Configure {{name}} to send syslog", + "step2Hint": "On the {{name}} device, point syslog forwarding to the collector's address on {{port}}.", + "vendorDocs": "See vendor-specific instructions", + "step3Title": "3 · Verify", + "step3Body": "Within a few minutes you should see {{name}} events under source: {{source}} in Log Explorer, and a new entry in Data Sources.", + "endpoint": { + "title": "Connection details", + "hint": "Configure {{name}} to forward its logs to the Collector using the host and port below." + }, + "syslog": { + "sections": { + "sendLogs": { + "title": "1 · Send logs to UTMStack", + "body": "Configure your device to send syslog messages over UDP (514) or TCP (514) to the UTMStack agent." + }, + "enableCollector": { + "title": "2 · Enable the syslog collector", + "body": "Enable the log collector and the syslog integration in the configuration file where your UTMStack agent is installed." + }, + "activate": { + "title": "3 · Activate", + "body": "Activate the UTMStack module so events start flowing into Log Explorer." + } + } + }, + "netflow": { + "source": "Network device", + "step1": { + "title": "Enable the NetFlow listener on the Collector", + "body": "On the host where the Collector is installed, run this command to open the NetFlow collector on port 2055:", + "note": "NetFlow uses UDP only — TCP and TLS are not supported for this protocol." + }, + "step2": { + "title": "Configure your device to export NetFlow", + "body": "Point NetFlow export on your router or firewall at the Collector host on port {{port}} UDP. The example below is for Cisco IOS — consult your vendor's documentation for other platforms:", + "note": "Replace with the interface name where traffic should be monitored (e.g. GigabitEthernet0/0). Apply ingress/egress on each relevant interface." + } + }, + "cisco": { + "source": "Cisco ASA", + "step1": { + "title": "Enable the Cisco ASA listener on the Collector", + "body": "On the host where the Collector is installed, run this command to open the Cisco ASA log listener:", + "note": "To use TCP instead of UDP, replace udp with tcp in the command above." + }, + "step2": { + "title": "Configure Cisco ASA to forward logs", + "body": "On your Cisco ASA, enable syslog and point it at the Collector host on port {{port}}. Run these commands in privileged EXEC mode (replace with your inside or management interface name):" + } + }, + "ciscoSwitch": { + "source": "Cisco Switch", + "step1": { + "title": "Enable the Cisco Switch listener on the Collector", + "body": "On the host where the Collector is installed, run this command to open the Cisco Switch log listener:", + "note": "To use TCP instead of UDP, replace udp with tcp in the command above." + }, + "step2": { + "title": "Configure the switch to forward logs", + "body": "In privileged EXEC mode on your Cisco switch, enable syslog and point it at the Collector host on port {{port}}:" + } + }, + "ciscoMeraki": { + "source": "Cisco Meraki", + "step1": { + "title": "Enable the Cisco Meraki listener on the Collector", + "body": "On the host where the Collector is installed, run this command to open the Cisco Meraki log listener:", + "note": "To use TCP instead of UDP, replace udp with tcp in the command above." + }, + "step2": { + "title": "Configure Meraki to forward logs", + "body": "In the Meraki Dashboard, go to Network-wide → Configure → General, scroll to the Reporting section and add a syslog server with the Collector IP and port {{port}}. Select all roles you want to forward." + } + }, + "ciscoFirepower": { + "source": "Cisco Firepower", + "step1": { + "title": "Enable the Cisco Firepower listener on the Collector", + "body": "On the host where the Collector is installed, run this command to open the Cisco Firepower log listener:", + "note": "To use TCP instead of UDP, replace udp with tcp in the command above." + }, + "step2": { + "title": "Configure Firepower to forward logs", + "body": "In Firepower Management Center (FMC), go to Devices → Platform Settings, edit or create a policy and navigate to Syslog → Syslog Servers. Add the Collector IP with port {{port}} (UDP), then assign the policy to your devices and deploy." + } + }, + "vmware": { + "source": "VMware ESXi", + "step1": { + "title": "Enable the VMware listener on the Collector", + "body": "On the host where the Collector is installed, run this command to open the VMware ESXi syslog listener. ESXi streams over TCP:", + "note": "For an encrypted channel use tls instead of tcp (load certificates on the Collector first)." + }, + "step2": { + "title": "Point ESXi syslog at the Collector", + "body": "Open an SSH/ESXi Shell session on the host (or use the vSphere Client: Host → Configure → Advanced System Settings → Syslog.global.logHost). Set the remote loghost to {{host}}:{{port}} and reload the configuration:", + "note": "On vSphere you can instead set Syslog.global.logHost to the same tcp://host:port value rather than running esxcli." + }, + "step3": { + "title": "Open the ESXi firewall for syslog", + "body": "Allow outbound syslog through the ESXi firewall so the host can reach the Collector:" + } + }, + "as400": { + "intro": { + "title": "How it works", + "body": "The AS/400 Collector is a Linux service that connects directly to your AS/400 (IBM i) systems and pulls security journal entries, then streams them securely to UTMStack for correlation and alerting.", + "note": "Nothing is installed on the AS/400 itself — the Collector runs on a Linux host that has network access to your AS/400 systems.", + "diagram": { + "source": "your journals", + "edge1": "journals", + "collector": "AS/400 Collector", + "collectorSub": "pulls from AS/400", + "edge2": "secure", + "utmstackSub": "alerts & correlation" + } + }, + "install": { + "title": "Install the AS/400 Collector", + "body": "Run this command on a Linux host that can reach both UTMStack and your AS/400 systems over the network.", + "reuse": "Already have the AS/400 Collector installed? Skip this step — just add your servers to the configuration file in the next step." + }, + "configure": { + "title": "Add your AS/400 servers", + "body": "Edit as400-config.yaml in the collector's installation directory and add each AS/400 system you want to monitor:", + "note": "You can list multiple servers. The collector watches this file and reloads automatically on save — no restart needed." + }, + "journal": { + "title": "Enable audit journaling on AS/400", + "body": "On each AS/400 system, make sure the QAUDJRN security audit journal is active. Refer to IBM's documentation for the exact steps — the procedure varies between IBM i versions." + }, + "uninstall": { + "title": "Optional — Uninstall the Collector", + "body": "Run this command on the host where the AS/400 Collector is installed to stop the service and remove all files." + } + }, + "bitdefender": { + "intro": { + "title": "How it works", + "body": "UTMStack connects to Bitdefender GravityZone using your API key to configure the Event Push Service. GravityZone then sends security events directly to UTMStack for correlation and alerting.", + "diagram": { + "source": "endpoint events", + "edge": "Event Push Service", + "utmstackSub": "alerts & correlation" + }, + "note": "No agent is installed on GravityZone — UTMStack registers itself as the push destination using read-only API credentials." + }, + "whitelist": { + "title": "Whitelist Bitdefender IPs", + "body": "The following Bitdefender GravityZone IP addresses must be allowed through your firewall on port 8000 so that the Event Push Service can reach UTMStack:", + "note": "Add these IPs to your firewall or security group before completing the setup." + }, + "apiSection": "Get API credentials", + "api": { + "myAccount": { + "title": "Open My Account", + "body": "In the Bitdefender GravityZone console, click on My Account." + }, + "accessUrl": { + "title": "Note the Access URL", + "body": "Scroll down to the Control Center API section and save the Access URL — you will enter it in the credentials form below. Then open the API key section and click Add at the top of the table." + }, + "createKey": { + "title": "Create an API key", + "body": "Write a description for the API key, select the Event Push Service API option, and click Save. Copy the generated key." + } + }, + "companySection": "Get Company IDs", + "company": { + "myCompany": { + "title": "Open My Company", + "body": "In the GravityZone console, click on My Company." + }, + "licensing": { + "title": "Note the Company IDs", + "body": "Open the Licensing section and save the Company IDs you want to monitor — enter them comma-separated in the credentials form below." + } + }, + "credentials": { + "title": "Enter credentials", + "body": "Fill in the Access URL, API key, your UTMStack public IP (where GravityZone will push events), and the Company IDs to monitor. UTMStack verifies the credentials before saving." + }, + "fields": { + "accessUrl": { + "label": "GravityZone Access URL" + }, + "connectionKey": { + "label": "API key" + }, + "utmPublicIP": { + "label": "UTMStack public IP" + }, + "companyIds": { + "label": "Company IDs (comma-separated)" + } + } + }, + "eset": { + "source": "ESET Protect", + "step1": { + "title": "Enable the ESET listener on the Collector", + "body": "On the host where the Collector is installed, run this command to open the ESET syslog listener:", + "note": "To use TCP instead of UDP, replace udp with tcp in the command above." + }, + "console": { + "moreMenu": { + "title": "Open the More menu", + "body": "In the ESET Protect console sidebar, click the More menu." + }, + "serverConfig": { + "title": "Open Server settings", + "body": "Under More, open the Server settings (Server configuration) section." + }, + "advanced": { + "title": "Expand Advanced settings", + "body": "Click Advanced settings to expand the full list of configuration options." + }, + "syslog": { + "title": "Configure the Syslog server", + "body": "Scroll to Syslog server, enable Export logs to Syslog, and set the destination to the Collector host on port {{port}} (UDP). ESET sends LEEF/syslog, which the Collector ingests as the antivirus-esmc-eset data type." + } + } + }, + "kaspersky": { + "source": "Kaspersky Security", + "step1": { + "title": "Enable the Kaspersky listener on the Collector", + "body": "On the host where the Collector is installed, run this command to open the Kaspersky syslog listener:", + "note": "To use TCP instead of UDP, replace udp with tcp in the command above." + }, + "console": { + "consoleSettings": { + "title": "Open Console settings → Integration", + "body": "In the Kaspersky Security Center sidebar, open Console settings and click the Integration submenu." + }, + "siem": { + "title": "Open the SIEM integration settings", + "body": "Under Integration, select SIEM and click the Settings link to open the export configuration." + }, + "configure": { + "title": "Configure the SIEM export", + "body": "Enable export and set Kaspersky to send events in Splunk (CEF) format to the Collector host on port {{port}} (UDP). The Collector ingests them as the antivirus-kaspersky data type." + } + } + }, + "sophos": { + "intro": { + "title": "Sophos Central — API Plugin", + "body": "Sophos Central provides secure APIs to retrieve event and alert data. UTMStack connects to those APIs to centralize monitoring and enhance your security visibility — no agent or collector required.", + "diagram": { + "source": "Sophos Central API", + "edge": "HTTPS API", + "utmstackSub": "Ingests & correlates" + }, + "note": "UTMStack polls the Sophos Central API on a schedule. Ensure the API credentials you create below have read access to events and alerts." + }, + "apiSection": "Generate API Credentials in Sophos Central", + "steps": { + "apiCredentials": { + "title": "Open API Credentials Management", + "body": "In Sophos Central Admin, navigate to Global Settings → API Credentials Management." + }, + "addCredential": { + "title": "Create a new credential", + "body": "Click Add Credential. Provide a Name and Description, select the appropriate Role, then click Add." + }, + "copyIds": { + "title": "Copy Client ID and Client Secret", + "body": "Copy the Client ID and Client Secret and store them securely.", + "secretNote": "The Client Secret is shown only once. Save it somewhere safe before closing this dialog." + } + }, + "credentialsSection": "Connect to UTMStack", + "credentials": { + "title": "Add Sophos Central credentials", + "body": "Enter the credentials you just created. You can add more than one Sophos account by clicking Add config group." + }, + "fields": { + "clientId": { + "label": "Client ID" + }, + "apiKey": { + "label": "Client Secret / API Key" + } + } + }, + "webroot": { + "sections": { + "login": { + "title": "1 · Log in to the management console", + "body": "Log in to the Webroot management console. It opens on the Sites tab." + }, + "openSettings": { + "title": "2 · Open Settings", + "body": "Click on the Settings tab." + }, + "apiAccess": { + "title": "3 · Open API Access", + "body": "From the Subscriptions tab, click on the API Access tab." + }, + "createCredential": { + "title": "4 · Create a client credential", + "body": "Click New and fill in the Name and Description. Read the SecureAnywhere Business Solution and Unity API agreement, then click Create." + }, + "noteClientSecret": { + "title": "5 · Copy the client ID and secret", + "body": "Save the Client ID from the list and the Client Secret that's shown only once. Click \"I have made note of the client secret\" to confirm." + }, + "fillForm": { + "title": "6 · Fill the form", + "body": "Provide the client ID and client secret to UTMStack. You can add more than one Webroot config group if needed." + }, + "activate": { + "title": "7 · Activate", + "body": "Activate the UTMStack module so Webroot events start flowing." + } + } + }, + "sentinelOne": { + "source": "SentinelOne", + "step1": { + "title": "Enable the SentinelOne listener on the Collector", + "body": "On the host where the Collector is installed, run this command to open the SentinelOne syslog listener. SentinelOne streams CEF over TCP:", + "note": "For an encrypted channel use tls instead of tcp (load certificates on the Collector first)." + }, + "console": { + "settings": { + "title": "Open the SentinelOne Settings", + "body": "In the SentinelOne management console sidebar, click the Settings menu." + }, + "syslog": { + "title": "Configure the Syslog integration", + "body": "Go to Integrations → Syslog and enable it. Set the host to {{host}} and port to {{port}}, keep the format as CEF, click Test to verify the connection, then Save." + } + } + }, + "office365": { + "intro": { + "title": "How it works", + "body": "UTMStack connects to Microsoft 365 using a registered Azure AD app and polls the Office 365 Management Activity API for audit and security events. No agent is installed in your tenant.", + "diagram": { + "source": "audit & security events", + "edge": "Management API", + "utmstackSub": "correlation & alerts" + }, + "note": "UTMStack requires read-only API access — no write permissions are requested." + }, + "appSection": "Azure App Registration", + "steps": { + "azurePortal": { + "title": "Open Microsoft Entra ID", + "body": "Open the Azure Portal (portal.azure.com) and click on Microsoft Entra ID." + }, + "appRegistrations": { + "title": "Go to App registrations", + "body": "In the left menu, click App registrations." + }, + "registerApp": { + "title": "Register a new app", + "body": "Click New registration. Name it UTMStack O365 Agent, select Accounts in this organizational directory only (Single-tenant), and click Register." + }, + "clientSecret": { + "title": "Create a client secret", + "body": "Go to Certificates & Secrets → New client secret. Add a description, set expiry to 730 days (24 months), and click Add.", + "copyNote": "Copy the secret Value immediately — it is only shown once and cannot be retrieved later." + }, + "apiPermissions": { + "title": "Add Office 365 Management API permissions", + "body": "Go to API Permissions → Add a permission and search for Office 365 Management APIs." + }, + "activityFeed": { + "title": "Grant ActivityFeed permissions", + "body": "Select Application Permissions and add ActivityFeed.Read and ActivityFeed.ReadDlp. Click Grant admin consent and confirm." + }, + "graphPermissions": { + "title": "Add Microsoft Graph permissions", + "body": "Back in Add a permission, click Microsoft Graph." + }, + "delegatedPermissions": { + "title": "Add delegated SecurityAlert permissions", + "body": "Select Delegated Permissions and add SecurityAlert.Read.All and SecurityAlert.ReadWrite.All. Click Grant admin consent and confirm." + }, + "appPermissions": { + "title": "Add application SecurityAlert permissions", + "body": "Select Application Permissions and add SecurityAlert.Read.All and SecurityAlert.ReadWrite.All. Click Grant admin consent and confirm." + }, + "noteIds": { + "title": "Copy the app IDs", + "body": "Go to the app Overview and copy the Application (client) ID and Directory (tenant) ID. You also need the secret value copied in step 4." + } + }, + "credentialsSection": "Credentials", + "credentials": { + "title": "Connect your Microsoft 365 tenant", + "body": "Enter the details from the steps above. UTMStack verifies the credentials before saving. You can add multiple config groups." + }, + "fields": { + "tenantId": { + "label": "Tenant ID (Directory ID)" + }, + "clientId": { + "label": "Client ID (Application ID)" + }, + "clientSecret": { + "label": "Client Secret" + }, + "cloudEnv": { + "label": "Cloud Environment (optional)", + "hint": "Commercial (default), GCC, GCCHigh, or DoD" + } + } + }, + "github": { + "source": "GitHub", + "step1": { + "title": "Enable the GitHub webhook listener on the Collector", + "body": "On the host where the Collector is installed, run this command to open the HTTPS webhook listener for GitHub:", + "tokenNote": "The terminal will print a secret token — copy it immediately. It will not be shown again." + }, + "certWarning": { + "title": "GitHub requires a CA-signed TLS certificate", + "body": "GitHub only delivers webhooks to HTTPS endpoints with a certificate issued by a public CA (self-signed certificates are rejected). Make sure the Collector host has a valid domain certificate before registering the webhook." + }, + "step2": { + "title": "Register the webhook in GitHub", + "body": "In your repository or organization, go to Settings → Webhooks → Add webhook and fill in the form:", + "payloadUrl": "Payload URL", + "contentType": "Content type", + "secret": "Secret", + "secretHint": "Paste the token shown when the integration was enabled above.", + "events": "Which events", + "eventsHint": "Send me everything — or select specific event types." + } + }, + "salesforce": { + "sections": { + "openSetup": { + "title": "1 · Open Setup", + "body": "Go to Setup and select \"Setup for the current app\" at the top right of the screen." + }, + "appManager": { + "title": "2 · Open App Manager", + "body": "Type \"App Manager\" in the quick search box and select App Manager." + }, + "newConnectedApp": { + "title": "3 · Create a new Connected App", + "body": "On the Lightning Experience App Manager screen, click \"New Connected App\" and fill in the fields." + }, + "oauthSettings": { + "title": "4 · Enable OAuth Settings", + "body": "In the \"API (Enable OAuth Settings)\" section, check \"Enable OAuth Settings\" and use https://login.salesforce.com/services/oauth2/success as the Callback URL." + }, + "oauthScopes": { + "title": "5 · Add OAuth scopes", + "body": "Select \"Access Connect REST API resources (chatter_api)\" under Selected OAuth Scopes." + }, + "save": { + "title": "6 · Save", + "body": "Save your changes and select Continue on the next screen." + }, + "manageConsumer": { + "title": "7 · Open Manage Consumer Details", + "body": "Inside your Connected App, go to \"API (Enable OAuth Settings)\" and click \"Manage Consumer Details\" next to Consumer Key and Secret." + }, + "copyCredentials": { + "title": "8 · Copy the consumer key and secret", + "body": "Verify your identity. The Consumer Key and Consumer Secret appear under \"Consumer Details\". Copy both with the Copy button." + }, + "fillForm": { + "title": "9 · Fill the form", + "body": "Provide the Consumer Key, Consumer Secret, Salesforce username and password to UTMStack." + }, + "activate": { + "title": "10 · Activate", + "body": "Activate the UTMStack module so Salesforce events start flowing." + } + } + }, + "iis": { + "sections": { + "enableModule": { + "title": "1 · Enable the IIS Filebeat module", + "body": "On the UTMStack agent host, run:\ncd \"C:\\Program Files\\UTMStack\\UTMStack Agent\\beats\\filebeat\\\" && filebeat modules enable iis" + }, + "configureModule": { + "title": "2 · Configure the IIS module", + "body": "Edit C:\\Program Files\\UTMStack\\UTMStack Agent\\beats\\filebeat\\modules.d\\iis.yml as shown below to point at the IIS log directories you want to ship." + }, + "activate": { + "title": "3 · Activate", + "body": "Activate the UTMStack module so IIS events start flowing." + } + } + }, + "filebeat": { + "sections": { + "installRsyslog": { + "title": "1 · Install rsyslog", + "body": "Ensure rsyslog is installed on the host. Use your distribution's package manager (apt, dnf, yum)." + }, + "configureRsyslog": { + "title": "2 · Configure rsyslog to forward to UTMStack", + "body": "Edit /etc/rsyslog.conf (or a file under /etc/rsyslog.d/) and add a forwarding rule that targets the UTMStack agent over UDP or TCP on port 514." + }, + "restartRsyslog": { + "title": "3 · Restart rsyslog", + "body": "Restart the rsyslog service: sudo systemctl restart rsyslog" + }, + "enableCollector": { + "title": "4 · Enable the Linux logs collector", + "body": "Enable the log collector and the Linux Logs integration in the configuration file where your UTMStack agent is installed." + } + } + }, + "json": { + "sections": { + "overview": { + "title": "1 · Use the HTTP/JSON ingestion endpoint", + "body": "UTMStack accepts arbitrary JSON events over HTTPS. Send a POST request with a list of events; UTMStack parses them and routes through your configured parser." + }, + "auth": { + "title": "2 · Authenticate with a federation token", + "body": "Get a federation token from Settings → Connection Key and send it as a Bearer token in the Authorization header." + } + }, + "endpoint": { + "title": "JSON ingestion endpoint", + "hint": "Use this request shape from your application or a cron job. The token is the federation key from Settings → Connection Key." + } + }, + "ldap": { + "sections": { + "openServerManager": { + "title": "1 · Open Server Manager", + "body": "On the AD domain controller, open Server Manager." + }, + "addRoles": { + "title": "2 · Add Roles and Features", + "body": "Choose \"Add roles and features\" from the Manage menu." + }, + "selectCertServices": { + "title": "3 · Select Active Directory Certificate Services", + "body": "On the Server Roles step, select Active Directory Certificate Services." + }, + "installServices": { + "title": "4 · Install the Certificate Authority role service", + "body": "On the Role Services step, select Certificate Authority and finish the wizard." + }, + "configureAdCs": { + "title": "5 · Configure AD CS", + "body": "After install, click the notification to configure AD CS and choose Certificate Authority as the role service to configure." + }, + "pickCaType": { + "title": "6 · Pick the CA type", + "body": "Choose Enterprise CA → Root CA → Create a new private key." + }, + "setValidity": { + "title": "7 · Set the certificate validity period", + "body": "Set a validity period that fits your organization (5 years is typical)." + }, + "confirm": { + "title": "8 · Confirm and install", + "body": "Review the settings and click Configure to finish." + }, + "restart": { + "title": "9 · Restart the domain controller", + "body": "Restart the domain controller so LDAPS becomes available on TCP 636." + }, + "activate": { + "title": "10 · Activate", + "body": "Activate the UTMStack module so AD audit events start flowing." + } + } + }, + "oracle": { + "source": "Oracle DB server", + "step1": { + "title": "Enable the Oracle integration on the Collector", + "body": "On the server where the Collector is installed, run the following command to start listening for Oracle logs:", + "note": "The Collector will begin receiving syslog events from Oracle on port 7021." + }, + "step2": { + "title": "Configure rsyslog on the Oracle server", + "body": "Create the rsyslog configuration file:", + "editBody": "Open the file with your preferred editor and add the following configuration. Replace BASEDIR with your Oracle installation path (e.g., /u01/app/oracle) and with the Collector's IP address or hostname:", + "note": "Use @@:7021 instead of @ if you prefer TCP delivery." + }, + "step3": { + "title": "Restart rsyslog", + "body": "Apply the new configuration by restarting the rsyslog service:" + }, + "step4": { + "title": "Validate the configuration", + "body": "Send test log messages to verify that UTMStack is receiving events from all three Oracle log sources:", + "note": "Open Log Explorer and search for the test message text above to confirm they arrived." + } + }, + "vulnerabilities": { + "sections": { + "overview": { + "title": "1 · About the vulnerabilities scanner", + "body": "The UTMStack vulnerabilities module scans assets discovered through the Asset Management module and matches their fingerprint against the CVE database." + }, + "scope": { + "title": "2 · Define scan scope", + "body": "Use the Asset Management module to register the hosts you want scanned. The vulnerabilities scanner will run periodically against them." + }, + "activate": { + "title": "3 · Activate", + "body": "Activate the UTMStack module to start scanning." + } + } + }, + "assetScanner": { + "sections": { + "overview": { + "title": "1 · About Asset Management", + "body": "The Asset Management module discovers and inventories hosts, software, and services across your network." + }, + "agentRequirement": { + "title": "2 · Agent requirement", + "body": "Asset discovery uses UTMStack agents running on Linux, Windows, or macOS hosts. Install the agent on the systems you want inventoried." + }, + "activate": { + "title": "3 · Activate", + "body": "Activate the UTMStack module to start asset discovery." + } + } + }, + "fileIntegrity": { + "sections": { + "enableAuditPolicy": { + "title": "1 · Enable Audit Object Access", + "body": "On the Windows host, open Group Policy → Computer Configuration → Windows Settings → Security Settings → Advanced Audit Policy Configuration → Object Access and enable \"Audit File System\"." + }, + "configureFolderAuditing": { + "title": "2 · Configure folder auditing", + "body": "On each folder you want monitored, open Properties → Security → Advanced → Auditing and add an auditing entry for the principals and access types you care about." + }, + "verifyEvents": { + "title": "3 · Verify events appear in Security log", + "body": "Open Event Viewer and confirm 4663/4670 events are being generated when the audited objects are accessed." + }, + "activate": { + "title": "4 · Activate", + "body": "Activate the UTMStack module so file integrity events start flowing." + } + } + }, + "socAi": { + "sections": { + "overview": { + "title": "1 · About SOC AI", + "body": "SOC AI augments UTMStack with an LLM-backed analyst that summarizes alerts and suggests next steps. It runs against the provider you configure." + }, + "chooseProvider": { + "title": "2 · Choose a provider", + "body": "Pick a provider — OpenAI, Anthropic, Azure OpenAI, Google Gemini, Ollama, Mistral, DeepSeek, Groq, or a custom OpenAI-compatible endpoint." + }, + "configureCredentials": { + "title": "3 · Configure credentials", + "body": "Provide the API key and (where applicable) the model name and endpoint URL." + }, + "activate": { + "title": "4 · Activate", + "body": "Activate the UTMStack module so SOC AI starts working on alerts." + } + } + }, + "utmstack": { + "intro": { + "title": "How it works", + "body": "This integration self-monitors your UTMStack deployment. A lightweight collector installed on the UTMStack host tails the platform's own Docker container logs and ships them back into UTMStack for correlation and alerting.", + "diagram": { + "source": "Docker logs", + "sourceSub": "UTMStack containers", + "edge1": "tail", + "collector": "Collector", + "collectorSub": "on the host", + "edge2": "ingest", + "utmstackSub": "Correlates & alerts" + } + }, + "requirements": { + "title": "Runs on the UTMStack host only", + "body": "This integration can only be installed on a UTMStack instance running Ubuntu or a Red Hat-family distribution. Install the collector directly on the UTMStack server." + }, + "install": { + "title": "Install the collector", + "body": "On the UTMStack host, pick your operating system and run the command below to download and install the self-monitoring collector:", + "sensitiveWarning": "This command contains a sensitive connection token. Treat it like a password and don't share it." + }, + "after": { + "title": "What you'll see after installing", + "item1": "The collector registers itself and appears under Data sources.", + "item2": "UTMStack container logs start flowing within a minute.", + "item3": "Events become searchable in Log Explorer under the utmstack data type." + }, + "uninstall": { + "title": "Uninstall the collector", + "body": "To remove the self-monitoring collector from the UTMStack host, run:" + } + }, + "windowsFaa": { + "sections": { + "enableAuditPolicy": { + "title": "1 · Enable Audit Object Access", + "body": "On the Windows host, open Group Policy → Computer Configuration → Windows Settings → Security Settings → Advanced Audit Policy Configuration → Object Access and enable \"Audit File System\"." + }, + "configureFolderAuditing": { + "title": "2 · Configure folder auditing", + "body": "On each folder you want monitored, open Properties → Security → Advanced → Auditing and add an auditing entry for the principals and access types you care about." + }, + "activate": { + "title": "3 · Activate", + "body": "Activate the UTMStack module so file activity events start flowing." + } + } + }, + "awsBeanstalk": { + "sections": { + "openConsole": { + "title": "1 · Open the Elastic Beanstalk console", + "body": "In the AWS Console, open Elastic Beanstalk." + }, + "environment": { + "title": "2 · Open the environment management page", + "body": "Navigate to the management page for the environment you want to monitor." + }, + "configuration": { + "title": "3 · Open Configuration", + "body": "Choose Configuration." + }, + "software": { + "title": "4 · Modify the Software configuration", + "body": "In the Software configuration category, choose Modify." + }, + "s3LogStorage": { + "title": "5 · Enable S3 log storage", + "body": "Under S3 log storage, choose Rotate logs to upload rotated logs to Amazon S3." + }, + "cloudwatchStreaming": { + "title": "6 · Enable CloudWatch Logs streaming", + "body": "Under Instance log streaming to CloudWatch Logs, enable streaming, set the retention period, and pick whether to upload existing logs." + }, + "activate": { + "title": "7 · Activate", + "body": "Activate the UTMStack module so Beanstalk events start flowing." + } + } + }, + "awsFargate": { + "sections": { + "taskDefinition": { + "title": "1 · Update your task definition", + "body": "In the task definition for the Fargate task, set the logDriver to \"awslogs\" and define the log group name." + }, + "cloudwatchLogs": { + "title": "2 · Confirm CloudWatch Logs is receiving logs", + "body": "Open the CloudWatch Logs console and confirm the log group is being populated when tasks run." + }, + "iamPrerequisite": { + "title": "3 · IAM user prerequisite", + "body": "This integration shares credentials with the AWS IAM User module — make sure it's configured with CloudWatchLogsReadOnlyAccess." + }, + "activate": { + "title": "4 · Activate", + "body": "Activate the UTMStack module so Fargate events start flowing." + } + } + }, + "awsIamUser": { + "sections": { + "iamConsole": { + "title": "1 · Open the IAM console", + "body": "In the AWS console, go to IAM → Users → Add users." + }, + "createUser": { + "title": "2 · Create the user", + "body": "Pick a username (e.g. utmstack-ingest). Choose programmatic access." + }, + "programmaticAccess": { + "title": "3 · Set credential type", + "body": "Select \"Access key — Programmatic access\"." + }, + "attachPolicy": { + "title": "4 · Attach the CloudWatch read policy", + "body": "Attach the AWS-managed policy CloudWatchLogsReadOnlyAccess." + }, + "review": { + "title": "5 · Review the user", + "body": "Review the user details and click Create user." + }, + "copyKeys": { + "title": "6 · Copy the access key ID and secret", + "body": "Copy the Access key ID and the Secret access key — the secret is shown only once." + }, + "createLogGroup": { + "title": "7 · Create a CloudWatch log group", + "body": "In CloudWatch → Log groups, create a log group named \"utmstack\" — other AWS integrations will deliver to it." + }, + "fillForm": { + "title": "8 · Fill the form", + "body": "Provide the access key, secret, default region, and the log group name (e.g. \"utmstack\") to UTMStack." + }, + "activate": { + "title": "9 · Activate", + "body": "Activate the UTMStack module so AWS events start flowing." + } + } + }, + "awsLambda": { + "sections": { + "iamPrerequisite": { + "title": "1 · IAM user prerequisite", + "body": "Lambda relies on the AWS IAM User module — make sure that integration is configured first with CloudWatchLogsReadOnlyAccess." + }, + "cloudwatchStream": { + "title": "2 · Lambda already streams to CloudWatch Logs", + "body": "AWS Lambda automatically publishes execution logs to CloudWatch Logs under /aws/lambda/. UTMStack ingests from the log group you configured in the IAM user setup." + }, + "activate": { + "title": "3 · Activate", + "body": "Activate the UTMStack module so Lambda events start flowing." + } + } + }, + "awsSqlServer": { + "sections": { + "openRds": { + "title": "1 · Open the Amazon RDS console", + "body": "Open https://console.aws.amazon.com/rds/." + }, + "pickDb": { + "title": "2 · Pick the DB instance", + "body": "In the navigation pane, choose Databases and select the DB instance you want to monitor." + }, + "modify": { + "title": "3 · Modify the instance", + "body": "Choose Modify." + }, + "logExports": { + "title": "4 · Enable Log Exports", + "body": "In the Log exports section, choose Error log and Agent log to publish to CloudWatch Logs." + }, + "apply": { + "title": "5 · Apply changes", + "body": "Choose Continue, then Modify DB Instance on the summary page." + }, + "activate": { + "title": "6 · Activate", + "body": "Activate the UTMStack module so SQL Server events start flowing." + } + } + }, + "awsPostgresql": { + "sections": { + "openRds": { + "title": "1 · Open the Amazon RDS console", + "body": "Open https://console.aws.amazon.com/rds/." + }, + "pickDb": { + "title": "2 · Pick the DB instance", + "body": "In the navigation pane, choose Databases and select the DB instance you want to modify." + }, + "logExports": { + "title": "3 · Enable Log Exports", + "body": "In the Log exports section, choose the PostgreSQL log to publish to CloudWatch Logs." + }, + "apply": { + "title": "4 · Apply changes", + "body": "Choose Continue, then Modify DB Instance on the summary page." + }, + "activate": { + "title": "5 · Activate", + "body": "Activate the UTMStack module so PostgreSQL events start flowing." + } + } + }, + "awsTrafficMirror": { + "sections": { + "createTarget": { + "title": "1 · Create a traffic mirror target", + "body": "In the VPC console, create a Traffic Mirror Target that points at the network interface of the UTMStack agent VM." + }, + "createFilter": { + "title": "2 · Create a traffic mirror filter", + "body": "Create a Traffic Mirror Filter and add inbound/outbound rules for the protocols you want to mirror (e.g. all TCP, all UDP)." + }, + "createSession": { + "title": "3 · Create a traffic mirror session", + "body": "Create a Traffic Mirror Session that pairs each source network interface with the target and filter you created." + }, + "iamPrerequisite": { + "title": "4 · IAM user prerequisite", + "body": "Make sure the AWS IAM User module is also configured so UTMStack can read VPC flow logs if needed." + }, + "activate": { + "title": "5 · Activate", + "body": "Activate the UTMStack module so mirrored traffic starts being parsed." + } + } + }, + "forwarder": { + "intro": { + "title": "How it works", + "body": "Logs flow from {{source}} to the UTMStack Collector, which streams them securely into UTMStack for correlation and alerting. Nothing is installed on {{source}} — only the Collector needs to run on a host in your network." + }, + "diagram": { + "sourceSub": "your logs", + "forwarder": "Collector", + "forwarderSub": "listens on {{port}}", + "utmstack": "UTMStack", + "utmstackSub": "alerts & correlation", + "flow1": "logs", + "flow2": "secure" + }, + "noInstall": "Nothing is installed on {{source}} — you only redirect its logs to the Collector.", + "install": { + "title": "Install the UTMStack Collector", + "body": "The Collector is a Linux service that receives logs from your devices and sends them to UTMStack. A single Collector handles multiple integrations at the same time.", + "reuse": "Already have a Collector running? Skip this step — point {{source}} at the existing one using the host and port shown below." + }, + "tls": { + "title": "Optional — Enable TLS encryption", + "intro": "By default the listener accepts plain TCP/UDP. To encrypt syslog traffic in transit, load your certificate files first, then re-enable the listener with the tls protocol.", + "step1": "1 · Load your certificate and key (once per Collector)", + "step1Note": "An optional CA certificate can be added as a third argument. Omit it to use the leaf certificate as CA.", + "step2": "2 · Re-enable the listener using TLS" + }, + "httpsCerts": { + "title": "Load the TLS certificate on the Collector", + "body": "This integration uses an HTTPS listener on port {{port}}, so the Collector needs a certificate and key loaded before enabling it:" + }, + "uninstall": { + "title": "Optional — Uninstall the Collector", + "body": "Run this command on the host where the Collector is installed to stop the service and remove all its files." + }, + "manualCommand": { + "title": "Optional — Enable via the command line instead", + "intro": "Prefer the terminal? SSH into the Collector host and run the command below — it matches whatever protocol and port you have selected above.", + "certStep": "1 · Load your certificate and key (once per Collector)", + "enableStep": "2 · Enable the integration" + }, + "instanceHeader": { + "title": "Authorization header", + "body": "Include this Authorization header on every request you send to the instance. The API key's secret is revealed only once when it is generated — copy it then and paste it in place of the placeholder below.", + "tabSimple": "Simple", + "tabBatch": "Batch" + } + }, + "aix": { + "source": "AIX server", + "step1": { + "title": "Enable the AIX listener on the Collector", + "body": "On the host where the Collector is installed, run this command to open the AIX log listener:", + "note": "To use TCP instead of UDP, replace udp with tcp in the command above." + }, + "step2": { + "title": "Configure AIX to forward logs", + "body": "On your AIX system, configure the syslog service to redirect its logs to the Collector host on port {{port}}. Refer to IBM’s documentation for the exact syntax — it varies between AIX versions." + } + }, + "deceptivebytes": { + "source": "Deceptive Bytes", + "step1": { + "title": "Enable the Deceptive Bytes listener on the Collector", + "body": "On the host where the Collector is installed, run this command to open the Deceptive Bytes syslog listener:", + "note": "To use TCP instead of UDP, replace udp with tcp in the command above." + }, + "step2": { + "title": "Configure Deceptive Bytes to forward logs", + "body": "In the Deceptive Bytes management console, configure syslog forwarding to send events to the Collector host on port {{port}} (UDP). Deceptive Bytes emits CEF-formatted syslog, which the Collector ingests as the deceptive-bytes data type." + } + }, + "mikrotik": { + "source": "MikroTik router", + "step1": { + "title": "Enable the MikroTik listener on the Collector", + "body": "On the host where the Collector is installed, run this command to open the MikroTik syslog listener:", + "note": "To use TCP instead of UDP, replace udp with tcp in the command above." + }, + "step2": { + "title": "Configure MikroTik to forward logs", + "body": "On the MikroTik router, create a remote logging action pointing at the Collector host on port {{port}} and attach it to the relevant log topics. Run the following from the RouterOS CLI (Terminal in Winbox):", + "note": "You can also configure this via Winbox: System → Logging → Actions tab (add a Remote action) → then the Rules tab (add rules pointing to the new action)." + } + }, + "fortigate": { + "source": "FortiGate firewall", + "step1": { + "title": "Enable the FortiGate listener on the Collector", + "body": "On the host where the Collector is installed, run this command to open the FortiGate syslog listener:", + "note": "To use TCP instead of UDP, replace udp with tcp in the command above." + }, + "step2": { + "title": "Configure FortiGate to forward logs", + "body": "On the FortiGate, point syslog at the Collector host on port {{port}}. Run the following from the FortiOS CLI (or use Log & Report → Log Settings → Syslog in the GUI):", + "note": "Replace the server address if the Collector runs on a different host. For multiple syslog collectors use syslogd2/syslogd3/syslogd4." + } + }, + "fortiweb": { + "source": "FortiWeb WAF", + "step1": { + "title": "Enable the FortiWeb listener on the Collector", + "body": "On the host where the Collector is installed, run this command to open the FortiWeb syslog listener:", + "note": "To use TCP instead of UDP, replace udp with tcp in the command above." + }, + "step2": { + "title": "Configure FortiWeb to forward logs", + "body": "On the FortiWeb, create a syslog policy pointing at the Collector host on port {{port}} and enable syslog logging. Run the following from the FortiWeb CLI (or use Log & Report → Log Policy → Syslog Policy in the GUI):", + "note": "Make sure the relevant log types (Attack, Event, Traffic) are enabled to be sent to syslog under Log & Report settings." + } + }, + "paloalto": { + "source": "Palo Alto firewall", + "step1": { + "title": "Enable the Palo Alto listener on the Collector", + "body": "On the host where the Collector is installed, run this command to open the Palo Alto syslog listener:", + "note": "To use TCP instead of UDP, replace udp with tcp in the command above." + }, + "step2": { + "title": "Create a Syslog Server Profile", + "body": "In PAN-OS, go to Device → Server Profiles → Syslog and add a profile. Set the server address to {{host}}, transport UDP, port {{port}} and format BSD." + }, + "step3": { + "title": "Forward logs and commit", + "body": "Create a Log Forwarding profile (Objects → Log Forwarding) that sends Traffic, Threat and other log types to the syslog profile above, attach it to your Security policy rules (Policies → Security → rule → Actions → Log Forwarding), then Commit." + } + }, + "pfsense": { + "source": "pfSense firewall", + "step1": { + "title": "Enable the pfSense listener on the Collector", + "body": "On the host where the Collector is installed, run this command to open the pfSense syslog listener:", + "note": "To use TCP instead of UDP, replace udp with tcp in the command above." + }, + "step2": { + "title": "Enable Remote Logging in pfSense", + "body": "In the pfSense web UI, go to Status → System Logs → Settings. Under Remote Logging Options, check Enable Remote Logging, set a Remote log server to {{host}}:{{port}}, choose which logs to send (or Everything), and click Save." + } + }, + "sonicwall": { + "source": "SonicWall firewall", + "step1": { + "title": "Enable the SonicWall listener on the Collector", + "body": "On the host where the Collector is installed, run this command to open the SonicWall syslog listener:", + "note": "To use TCP instead of UDP, replace udp with tcp in the command above." + }, + "step2": { + "title": "Add a Syslog Server in SonicOS", + "body": "In SonicOS, go to Device → Log → Syslog (Manage → Log → Syslog on older firmware) and add a Syslog Server with address {{host}} and port {{port}}. Set the Syslog Format to ArcSight (CEF) — UTMStack parses SonicWall in CEF — then Apply." + } + }, + "sophosxg": { + "source": "Sophos Firewall", + "step1": { + "title": "Enable the Sophos Firewall listener on the Collector", + "body": "On the host where the Collector is installed, run this command to open the Sophos Firewall syslog listener:", + "note": "To use TCP instead of UDP, replace udp with tcp in the command above." + }, + "step2": { + "title": "Add a Syslog Server in Sophos Firewall", + "body": "In the Sophos Firewall (SFOS) console, go to System → System services → Log settings and add a Syslog Server with address {{host}} and port {{port}}. Choose the log types you want to forward (firewall, IPS, ATP, web, etc.) and click Apply." + } + }, + "suricata": { + "source": "Suricata IDS", + "step1": { + "title": "Enable the Suricata listener on the Collector", + "body": "On the host where the Collector is installed, run this command to open the Suricata listener:", + "note": "To use TCP instead of UDP, replace udp with tcp in the command above." + }, + "step2": { + "title": "Send Suricata EVE logs to syslog", + "body": "Suricata is ingested as JSON (EVE). On the Suricata host, edit suricata.yaml and configure the eve-log output to write to syslog:", + "note": "Then restart Suricata: sudo systemctl restart suricata" + }, + "step3": { + "title": "Forward syslog to the Collector", + "body": "Point the local5 facility (where Suricata now writes) at the Collector. Add this rule to /etc/rsyslog.d/60-utmstack-suricata.conf on the Suricata host:", + "note": "Use @@ instead of @ for TCP. Then restart rsyslog: sudo systemctl restart rsyslog" + } + }, + "o365_graph": { + "intro": { + "title": "How it works", + "body": "UTMStack connects to Microsoft 365 with a registered Azure AD app and polls Microsoft Graph for security events: alerts, incidents, directory audit, sign-ins, risk detections, hunting queries and Purview audit logs. No agent is installed in your tenant.", + "diagram": { + "source": "security events", + "edge": "Microsoft Graph", + "utmstackSub": "correlation & alerts" + }, + "note": "UTMStack requires read-only Graph API access — no write permissions are requested." + }, + "appSection": "Azure App Registration", + "steps": { + "azurePortal": { + "title": "Open Microsoft Entra ID", + "body": "Open the Azure Portal (portal.azure.com) and click on Microsoft Entra ID." + }, + "appRegistrations": { + "title": "Go to App registrations", + "body": "In the left menu, click App registrations." + }, + "registerApp": { + "title": "Register a new app", + "body": "Click New registration. Name it UTMStack Graph Dev, select Accounts in this organizational directory only (Single-tenant), and click Register." + }, + "clientSecret": { + "title": "Create a client secret", + "body": "Go to Certificates & Secrets → New client secret. Add a description, set expiry to 730 days (24 months), and click Add.", + "copyNote": "Copy the secret Value immediately — it is only shown once and cannot be retrieved later." + }, + "apiPermissions": { + "title": "Add Microsoft Graph permissions", + "body": "Go to API Permissions → Add a permission and select Microsoft Graph, then choose Application permissions." + }, + "graphPermissions": { + "title": "Add the four Graph permissions", + "body": "Add SecurityEvents.Read.All, Directory.Read.All, AuditLog.Read.All and IdentityRiskEvent.Read.All." + }, + "adminConsent": { + "title": "Grant admin consent", + "body": "Back in API Permissions, click Grant admin consent for {tenant} and confirm." + }, + "noteIds": { + "title": "Copy the app IDs", + "body": "Go to the app Overview and copy the Application (client) ID and Directory (tenant) ID. You also need the secret value copied in step 4." + } + }, + "credentialsSection": "Credentials", + "credentials": { + "title": "Connect your Microsoft 365 tenant", + "body": "Enter the details from the steps above. UTMStack verifies the credentials before saving. You can add multiple config groups." + }, + "fields": { + "tenantId": { + "label": "Tenant ID (Directory ID)" + }, + "clientId": { + "label": "Client ID (Application ID)" + }, + "clientSecret": { + "label": "Client Secret" + }, + "cloudEnv": { + "label": "Cloud Environment (optional)", + "hint": "Commercial (default), GCC, GCCHigh, or DoD" + } + } + } + }, + "cloud": { + "howItWorksTitle": "How it works", + "howItWorksBody": "{{name}} runs entirely inside UTMStack — no agent or collector to deploy. Provide read-only API credentials and UTMStack will pull events on a schedule, parse them, and ingest them into Log Explorer.", + "connectionTitle": "Connection", + "noFields": "No connection fields configured.", + "testConnection": "Test connection", + "save": "Save", + "afterTitle": "What you'll see after connecting", + "after1": "UTMStack performs an initial backfill of recent events.", + "after2": "From then on, events are pulled every 1–5 minutes (depends on the API).", + "after3": "The integration appears under Data Sources with current pull status and lag.", + "tenants": { + "title": "Configured config groups", + "empty": "No config groups configured yet. Add your first one below.", + "loading": "Loading config groups…", + "nameLabel": "Config group name", + "namePlaceholder": "e.g. acme-prod", + "add": "Add config group", + "update": "Update config group", + "delete": "Delete", + "edit": "Edit", + "cancel": "Cancel", + "editing": "Editing: {{name}}", + "selectFile": "Select file", + "replaceFile": "Replace file", + "fileLoaded": "File loaded", + "invalidJson": "Could not parse the file as JSON.", + "createError": "Could not create the config group. Please try again.", + "updateError": "Could not update the config group. Please try again.", + "createSuccess": "Config group created successfully.", + "updateSuccess": "Config group updated successfully." + }, + "google": { + "intro": { + "title": "How it works", + "body": "UTMStack reads audit activity directly from Google Cloud via Pub/Sub. A Logs Router sink streams your project logs into a Pub/Sub topic; UTMStack runs an internal puller that reads a Pull subscription on that topic using a service-account key. Nothing is installed in your GCP project.", + "diagram": { + "source": "Cloud Logging", + "edge1": "Logs Router", + "pubsub": "Pub/Sub", + "pubsubSub": "topic + subscription", + "edge2": "pulls", + "utmstackSub": "alerts & correlation" + }, + "note": "No agent runs in GCP — UTMStack pulls messages from the Pub/Sub subscription using the service-account JSON key you provide below." + }, + "sections": { + "createTopic": { + "title": "Create a Pub/Sub topic", + "body": "In the Google Cloud console, open Pub/Sub → Topics and create a new topic. The Logs Router sink will publish your project logs to it.", + "docLabel": "Open the Pub/Sub topics page" + }, + "createSubscription": { + "title": "Create a subscription", + "body": "From the topic menu, create a subscription. UTMStack pulls messages from this subscription." + }, + "configureSubscription": { + "title": "Configure the subscription", + "body": "Leave the Delivery type as Pull and the Expiration as Never expire. The default acknowledgement deadline (10s) and message retention are fine." + }, + "logsRouter": { + "title": "Open Logs Router and create a sink", + "body": "Navigate to Logging → Logs Router and create a new sink. This is what forwards your project logs into the Pub/Sub topic above." + }, + "sinkDestination": { + "title": "Point the sink at the topic", + "body": "Choose Cloud Pub/Sub topic as the sink destination and select the topic you created. Optionally use inclusion/exclusion filters to scope which logs are forwarded, then create the sink." + }, + "serviceAccount": { + "title": "Create a service account", + "body": "Open IAM & Admin → Service Accounts in the project that holds your topic and sink, and create a new service account. Grant it the Pub/Sub Editor role so UTMStack can pull from the subscription.", + "docLabel": "Open the service accounts page" + }, + "serviceAccountKey": { + "title": "Generate a key for the service account", + "body": "Open the service account, go to the Keys tab, and add a new key. Choose JSON as the key type." + }, + "downloadKey": { + "title": "Download the JSON key", + "body": "Save the JSON file Google downloads — its contents go in the Service account JSON key field below. The key is shown only once." + } + }, + "credentials": { + "title": "Pub/Sub configuration", + "body": "Use the values collected above to configure UTMStack. You can monitor more than one project by saving additional configurations.", + "mapping": { + "intro": "Field reference", + "projectId": "Project ID — the GCP project that holds your topic, subscription and sink", + "subscription": "Subscription name — the Pull subscription created in step 2", + "jsonKey": "Service account JSON key — the file downloaded in step 8" + } + }, + "fields": { + "projectId": { + "label": "Project ID" + }, + "subscription": { + "label": "Subscription name" + }, + "jsonKey": { + "label": "Service account JSON key" + } + } + }, + "azure": { + "intro": { + "title": "How it works", + "body": "UTMStack reads audit activity directly from an Azure Event Hub. You configure your Azure subscription to stream events into an Event Hub; UTMStack runs an internal puller that reads that hub and checkpoints its progress in a Storage Account. Nothing is installed in your Azure tenant.", + "diagram": { + "source": "subscription events", + "edge1": "streams to", + "eventHub": "Event Hub", + "eventHubSub": "event stream", + "edge2": "pulls", + "utmstackSub": "alerts & correlation" + }, + "note": "No agent runs in Azure — UTMStack pulls events from the Event Hub using the connection strings you provide below." + }, + "sections": { + "createEventHub": { + "title": "Create an Event Hub", + "body": "In the Azure Portal, create an Event Hubs namespace and an Event Hub inside it. UTMStack will read events from this hub.", + "docLabel": "Quickstart: Create an event hub using the Azure portal" + }, + "sharedAccessPolicy": { + "title": "Add a Shared Access Policy", + "body": "Open the Event Hub → Shared access policies and create a new policy. Make sure you select the Listen permission." + }, + "connectionString": { + "title": "Copy the primary connection string", + "body": "Open the Shared access policy you just created and copy the Connection string–primary key. You will use it to configure your config group below." + }, + "consumerGroup": { + "title": "Create a dedicated consumer group", + "body": "Get the Consumer Group name in: All services → Event Hubs → your namespace → Event Hubs → your instance → Consumer groups. You will use it to configure your config group below.", + "warn": "Create a consumer group specifically for UTMStack. Do not use $Default or any other group already in use — reusing a consumer group across unrelated consumers can cause unexpected behavior and lost events. All UTMStack instances should share the same consumer group so they can process events together." + }, + "createStorageAccount": { + "title": "Create a Storage Account", + "body": "UTMStack needs a Storage Account to checkpoint its read position. Create one in the same region as the Event Hub.", + "docLabel": "Quickstart: Create a storage account" + }, + "storageContainer": { + "title": "Get the Storage Container name", + "body": "Get the Storage Container name in: All services → Storage accounts → your account → Containers. You will use it to configure your config group below." + }, + "storageConnection": { + "title": "Copy the Storage Account connection string", + "body": "Get the Storage Account connection string with key in: All services → Storage accounts → your account → Access keys. UTMStack uses it to store Event Hub checkpoints." + }, + "eventGrid": { + "title": "Register the Event Grid resource provider", + "body": "Configure your subscription to send logs to the Event Hub. Go to Subscriptions → Resource providers, search for Event Grid (Microsoft.EventGrid) and make sure it is registered." + }, + "createEventSubscription": { + "title": "Create an Event Subscription", + "body": "In the subscription Events panel, create a new event by clicking Events → Event Subscription." + }, + "configureEventSubscription": { + "title": "Point the Event Subscription at your Event Hub", + "body": "Configure the Event Subscription to send logs to the Event Hub you created in step 1." + } + }, + "sampleLabel": "Sample connection string:", + "credentials": { + "title": "Event Hub configuration", + "body": "Use the data collected in the steps above to configure UTMStack. You can add more than one Event Hub by saving additional configurations.", + "mapping": { + "intro": "Field reference", + "eventHubConnection": "Event Hub connection string — value obtained in step 3", + "consumerGroup": "Consumer group — value obtained in step 4", + "storageContainer": "Storage container name — value obtained in step 6", + "storageConnection": "Storage account connection string — value obtained in step 7" + } + }, + "fields": { + "eventHubConnection": { + "label": "Event Hub connection string" + }, + "consumerGroup": { + "label": "Consumer group" + }, + "storageContainer": { + "label": "Storage container name" + }, + "storageConnection": { + "label": "Storage account connection string" + } + } + }, + "aws": { + "intro": { + "title": "How it works", + "body": "UTMStack reads audit activity directly from AWS CloudWatch Logs. CloudTrail captures API calls and management events across your AWS account, forwards them to a CloudWatch log group, and UTMStack polls that group to ingest and correlate events.", + "diagram": { + "source": "API events", + "edge1": "CloudTrail", + "cloudwatchSub": "log groups", + "edge2": "polls", + "utmstackSub": "alerts & correlation" + }, + "note": "No agent is installed on AWS — UTMStack pulls log events using read-only IAM credentials you provide below." + }, + "iamSection": "Configure IAM User", + "iam": { + "dashboard": { + "title": "Open the IAM dashboard", + "body": "Open the AWS console, navigate to the IAM dashboard and select Users." + }, + "addUser": { + "title": "Add a user", + "body": "Click Add user, enter a descriptive user name, and proceed to the next step." + }, + "attachPolicy": { + "title": "Attach the read-only policy", + "body": "Under Permissions, attach the required policy. Select CloudWatchLogsReadOnlyAccess for read-only CloudWatch access." + }, + "createUser": { + "title": "Create the user", + "body": "Review the configuration and click Create user to provision the account." + }, + "openUser": { + "title": "Open the new user", + "body": "Open the newly created user by clicking its name to view details and manage credentials." + }, + "securityTab": { + "title": "Go to Security credentials", + "body": "Select the Security credentials tab to create programmatic access keys." + }, + "createKey": { + "title": "Create an access key", + "body": "Click Create access key and choose the option for an application running outside AWS (programmatic access)." + }, + "confirmKey": { + "title": "Confirm creation", + "body": "Confirm creation of the access key. AWS will generate an Access Key ID and Secret Access Key." + }, + "downloadKey": { + "title": "Save your credentials", + "body": "Download the credentials file or copy the Access Key ID and Secret Access Key to a secure location — the Secret Access Key is only shown once." + } + }, + "credentials": { + "title": "Enter credentials", + "body": "Paste the Access Key ID and Secret Access Key obtained in the previous steps. UTMStack verifies the credentials against AWS before saving." + }, + "cloudwatchSection": "Configure AWS CloudWatch", + "cloudwatch": { + "createGroup": { + "title": "Create a CloudWatch Log Group", + "body": "Open the CloudWatch console, choose Log management and click Create log group." + }, + "nameGroup": { + "title": "Name the log group and set retention", + "body": "Enter the log group name utmstack and set retention to 1 day. Click Create log group." + }, + "openTrail": { + "title": "Open CloudTrail and create a trail", + "body": "In the CloudTrail console click Create trail to begin configuring a new trail." + }, + "configureTrail": { + "title": "Configure delivery, validation and CloudWatch integration", + "body": "On the CloudTrail creation form set the following options:", + "items": [ + "Trail name and scope: enter a descriptive name; enable Apply trail to all accounts in my organization if you need org-wide collection.", + "S3 destination: choose Create new S3 bucket (or select an existing bucket) for raw log delivery.", + "Encryption: enable Log file SSE-KMS and select the appropriate KMS key.", + "Log file validation: enable to ensure integrity of delivered logs (recommended).", + "CloudWatch Logs: enable delivery to CloudWatch, select Use existing log group and enter the exact name utmstack.", + "IAM role: provide or create the role CloudTrail will assume to write to S3 and publish to CloudWatch." + ] + }, + "eventTypes": { + "title": "Select event types", + "body": "Enable the event categories required for monitoring and auditing.", + "management": { + "label": "1 · Management events", + "body": "Enable Management events and select All to record all API activity that manages AWS resources (create, update, delete)." + }, + "data": { + "label": "2 · Data events", + "body": "Add a Data event. Choose S3 and select Log all events to capture object-level operations such as GetObject and PutObject." + }, + "network": { + "label": "3 · Network activity events", + "body": "In the Network Activities section add at least one service (e.g. ec2.amazonaws.com) and enable Log all events." + } + }, + "review": { + "title": "Review and create the trail", + "body": "On the Configure event aggregation screen accept the defaults (or adjust if required). Review all settings and click Create trail." + } + }, + "fields": { + "accessKeyId": { + "label": "AWS access key ID" + }, + "secretAccessKey": { + "label": "AWS secret access key" + }, + "region": { + "label": "AWS default region" + }, + "logGroupName": { + "label": "Log group name" + } + } + }, + "crowdstrike": { + "intro": { + "title": "How it works", + "body": "UTMStack reads detections and audit activity directly from the CrowdStrike Falcon Event Streams API. You create an API client in Falcon with Event Streams scope; UTMStack runs an internal puller that streams events using those credentials. Nothing is installed on your endpoints or in Falcon.", + "diagram": { + "source": "detections & events", + "edge1": "Event Streams API", + "api": "Falcon API", + "apiSub": "event stream", + "edge2": "pulls", + "utmstackSub": "alerts & correlation" + }, + "note": "No agent is deployed by UTMStack — it pulls events from Falcon using the read-only API client credentials you provide below." + }, + "sections": { + "apiClients": { + "title": "Open API Clients and Keys", + "body": "In the Falcon console, open the menu (hamburger icon, top-left) and go to Support and resources → API Clients and Keys." + }, + "createClient": { + "title": "Create a new API client", + "body": "Click Create API Client to start a new client definition." + }, + "scopes": { + "title": "Name the client and grant Event Streams scope", + "body": "Give the client a descriptive name (UTMStack uses it to identify the event source) and select the API scopes required for Event Streams. Click Create to generate the credentials." + }, + "recordCredentials": { + "title": "Record the credentials", + "body": "Copy the Client ID, Client Secret and the Base URL for your CrowdStrike region. The secret is shown only once — store it securely. You will paste all three into the form below." + } + }, + "credentials": { + "title": "API client configuration", + "body": "Use the credentials from the steps above to configure UTMStack. You can add more than one CrowdStrike client by saving additional configurations.", + "mapping": { + "intro": "Field reference", + "appName": "App name — the descriptive client name from step 3 (identifies the event source)", + "clientId": "Client ID — value recorded in step 4", + "clientSecret": "Client Secret — value recorded in step 4 (shown only once)", + "cloudRegionUrl": "Base URL — your region endpoint, e.g. https://api.crowdstrike.com (us-1), https://api.us-2.crowdstrike.com (us-2), https://api.eu-1.crowdstrike.com (eu-1)" + } + }, + "fields": { + "appName": { + "label": "App name" + }, + "clientId": { + "label": "Client ID" + }, + "clientSecret": { + "label": "Client Secret" + }, + "cloudRegionUrl": { + "label": "Base URL (cloud region)" + } + } + } + }, + "custom": { + "intro": { + "title": "How it works", + "body": "A custom integration ingests logs from any source the built-in modules do not cover. You install the UTMStack Collector, register a listener for your data with the protocol of your choice, and point your source at it.", + "note": "Pick the protocol your source can send (syslog UDP/TCP/TLS, or HTTP/HTTPS for JSON) below — the Collector creates the data type automatically." + }, + "diagram": { + "source": "Your source", + "sourceSub": "any app or device", + "forwarder": "Collector", + "ingests": "ingests", + "utmstackSub": "alerts & correlation" + }, + "choose": { + "title": "Choose protocol and port", + "body": "Select how your source sends data and the port the Collector should listen on, then run the activation command on the Collector host.", + "portLabel": "Listener port", + "tlsFirst": "First load your TLS certificate and key on the Collector:", + "enableLabel": "Then enable the integration:", + "authNote": "To require authentication, append --auth bearer (token) or --auth hmac — the Collector prints a token to use in the Authorization header." + }, + "send": { + "title": "Point your source at the Collector", + "bodyNetwork": "Configure your source to send {{proto}} syslog to {{host}}:{{port}}. Most devices have a remote-syslog or log-forwarding setting for this.", + "bodyHttp": "Send your events as JSON via HTTP POST to {{endpoint}}. Each request body is one JSON event:", + "httpBindNote": "The HTTP/HTTPS listener binds to 127.0.0.1 (the Collector host) by default, so post from an app running on that host — or front it with a reverse proxy. For remote sources, use syslog (UDP/TCP/TLS)." + }, + "parserTitle": "Parsing", + "parserBody": "Incoming events are stored under the {{dataType}} data type. Add a parsing filter for it so the raw payload is mapped into structured fields, then build alert rules on top.", + "manualCommand": { + "title": "Optional — Enable via the command line instead", + "intro": "Prefer the terminal? SSH into the Collector host and run the command below — it matches whatever protocol and port you have selected above." + }, + "whenTitle": "When to use this", + "whenBody": "Use this when your source is not in the catalog. Forward syslog or arbitrary JSON to UTMStack and set a parser to normalize the fields.", + "endpointsTitle": "Endpoints", + "syslogUdp": "Syslog (UDP)", + "syslogTls": "Syslog (TLS)", + "httpJson": "HTTP / JSON", + "payloadTitle": "Sample JSON payload", + "openEditor": "Open parser editor", + "powershellLabel": "PowerShell (run as administrator)", + "linuxLabel": "Linux — bash", + "macosLabel": "macOS — bash", + "exampleLabel": "Example syslog target on {{name}}:" + }, + "remoteEnable": { + "title": "Enable this integration remotely", + "body": "Pick a Collector, choose the protocol and port, then enable the integration — no SSH needed.", + "noPermission": "You don't have permission to manage remote integrations. Ask an administrator to grant the integrations.write permission.", + "loadingCollectors": "Loading Collectors…", + "noCollectors": "No Collector is registered yet. Install one above to enable integrations remotely.", + "forwarderOffline": "This Collector is offline and can't receive configuration changes right now.", + "legendOnline": "{{count}} online", + "legendOffline": "{{count}} offline", + "legendTotal": "{{count}} total", + "forwarderLabel": "Collector", + "protoLabel": "Protocol", + "portLabel": "Port", + "currentStateLoading": "Checking current configuration…", + "currentlyEnabled": "Currently: enabled · {{proto}} · port {{port}}", + "currentlyDisabled": "Currently: disabled · {{proto}} · port {{port}}", + "authLabel": "Authentication", + "authNone": "None", + "authBearer": "Bearer token", + "authHmac": "HMAC signature", + "pathLabel": "Path", + "signatureHeaderLabel": "Signature header", + "certTitle": "TLS certificate", + "certLoading": "Checking certificate status…", + "certLoaded": "A valid certificate is already loaded on this Collector.", + "certMissing": "No certificate loaded yet — upload one to enable this protocol.", + "certInvalid": "The loaded certificate is invalid: {{error}}", + "certPemLabel": "Certificate", + "keyPemLabel": "Private key", + "caPemLabel": "CA certificate", + "uploadCertsButton": "Upload certificate", + "certUploadSuccess": "Certificate uploaded.", + "certUploadError": "Failed to upload the certificate.", + "certReadError": "Could not read the selected file(s).", + "enableButton": "Enable integration", + "disableButton": "Disable integration", + "enableSuccess": "Integration enabled.", + "disableSuccess": "Integration disabled.", + "enableError": "Failed to update the integration.", + "secretWarning": "Store this token securely — it won't be shown again.", + "sendToInstance": "Send to instance", + "enterpriseFeature": "This is an Enterprise feature.", + "addCollector": "Add Collector", + "addApiKey": "Add API key", + "apiKeyLabel": "API key", + "apiKeyHint": "First you'll need an API key.", + "apiKeyPlaceholder": "Select an API key", + "apiKeyAddNew": "Add API key…", + "apiKeyNone": "No API keys yet", + "forwarderNoRemoteControl": "This forwarder was installed with remote control disabled. It ignores configuration sent from here, which can only be changed on the machine itself." + } + }, + "codeBlock": { + "copy": "Copy", + "copied": "Copied" + }, + "createDrawer": { + "title": "New custom integration", + "moduleName": "Module name", + "moduleNameHint": "Unique identifier. No spaces.", + "moduleNamePlaceholder": "my-custom-app", + "prettyName": "Display name", + "prettyNamePlaceholder": "My Custom App", + "dataType": "Data type", + "dataTypePlaceholder": "Unique identifier for this data type", + "icon": "Icon", + "iconHint": "PNG, SVG, JPEG, GIF or WEBP. Max 3MB. Used as the integration logo.", + "iconPreview": "Icon preview", + "dataTypeExists": "This data type already exists", + "invalidFileType": "Icon must be a valid image file (PNG, JPEG, SVG, GIF, WEBP)", + "fileTooLarge": "Icon must not exceed 3MB", + "fileReadError": "Failed to read file", + "cancel": "Cancel", + "create": "Create integration", + "creating": "Creating…", + "editTitle": "Edit integration", + "save": "Save", + "saving": "Saving…", + "currentIcon": "Current icon — upload a file to replace it", + "name": "Integration name", + "namePlaceholder": "e.g. Acme Firewall", + "description": "Description", + "descriptionPlaceholder": "What this integration ingests and why (optional)", + "identifierHint": "Stored as “{{id}}” (derived from the name)", + "nameTaken": "That integration name can’t be used — an integration with that identifier already exists.", + "removeIcon": "Remove icon", + "defaultIconNote": "Default icon — upload a file to use your own." + }, + "toast": { + "created": "Integration created", + "updated": "Integration updated", + "updateError": "Failed to update integration" + }, + "delete": { + "title": "Delete integration", + "confirm": "Delete this integration?", + "yes": "Delete", + "no": "Cancel", + "deleted": "Integration deleted", + "error": "Failed to delete integration" + }, + "modules": { + "WINDOWS_AGENT": "Collect Windows system, security and event-log activity through the lightweight UTMStack agent installed on each host.", + "LINUX_AGENT": "Collect Linux system, authentication and audit logs through the lightweight UTMStack agent installed on each host.", + "MACOS": "Collect macOS system and security log activity from Apple Mac endpoints through the lightweight UTMStack agent.", + "VMWARE": "Ingest VMware ESXi hypervisor syslog so virtualization-host activity and events are monitored within UTMStack.", + "NETFLOW": "Ingest NetFlow records from routers and switches to monitor network-traffic patterns and detect traffic anomalies.", + "AWS_IAM_USER": "Ingest AWS account activity and API calls via CloudTrail and CloudWatch to audit cloud usage, access and changes.", + "AZURE": "Ingest Microsoft Azure platform and activity logs to monitor cloud workloads, identity and resource changes.", + "O365": "Ingest Microsoft 365 audit logs across Exchange, Teams, SharePoint and OneDrive to monitor user and admin activity.", + "O365_GRAPH": "Ingest Microsoft Graph security events — alerts, incidents, directory audit, sign-ins, risk detections and Purview audit logs — to monitor identity and threat activity across your tenant.", + "GCP": "Ingest Google Cloud Platform audit and activity logs to monitor compute, storage and identity across projects.", + "KASPERSKY": "Ingest Kaspersky Security Center detections and endpoint telemetry to correlate malware activity across the network.", + "ESET": "Ingest ESET PROTECT endpoint detections and telemetry to correlate multilayered malware defense across your estate.", + "BITDEFENDER": "Ingest Bitdefender GravityZone detections and endpoint telemetry to correlate threats across business devices.", + "SENTINEL_ONE": "Ingest SentinelOne endpoint detections and behavioral telemetry to correlate and investigate threats at scale.", + "SOPHOS": "Ingest Sophos Central detections across endpoint, server, firewall and email to correlate threats in one place.", + "CROWDSTRIKE": "Ingest CrowdStrike Falcon endpoint and workload detections to correlate cloud-native threat activity in UTMStack.", + "CISCO": "Ingest Cisco ASA firewall traffic, VPN and threat logs to monitor perimeter security and access within UTMStack.", + "MERAKI": "Ingest Cisco Meraki firewall and security-appliance syslog to monitor cloud-managed network traffic and threats.", + "FIRE_POWER": "Ingest Cisco Firepower NGFW and IPS logs to monitor intrusion attempts and threat activity at the perimeter.", + "CISCO_SWITCH": "Ingest Cisco switch syslog and telemetry to monitor network performance, configuration changes and security.", + "FORTIGATE": "Ingest Fortinet FortiGate NGFW traffic and threat logs to monitor perimeter security and network activity.", + "FORTIWEB": "Ingest Fortinet FortiWeb WAF logs to monitor web-application attacks and protect exposed services and APIs.", + "SOPHOS_XG": "Ingest Sophos XG firewall logs covering web filtering, IPS and VPN to monitor network traffic and threats.", + "PALO_ALTO": "Ingest Palo Alto Networks NGFW traffic and threat logs to monitor application usage and perimeter security.", + "SONIC_WALL": "Ingest SonicWall NGFW traffic and threat logs to monitor perimeter security and network activity in UTMStack.", + "PFSENSE": "Ingest pfSense firewall and router logs with unified threat management to monitor network traffic and threats.", + "MIKROTIK": "Ingest MikroTik RouterOS firewall, routing and wireless logs to monitor network activity and configuration.", + "AIX": "Collect IBM AIX Unix system, security and audit logs to monitor activity on IBM Power platforms within UTMStack.", + "AS_400": "Collect IBM AS/400 (IBM i) system and audit journals to monitor user activity on midrange OS/400 platforms.", + "ORACLE": "Ingest Oracle Database audit logs to monitor queries, access and privileged activity across your databases.", + "SURICATA": "Ingest Suricata IDS/IPS alerts and network events to detect intrusions and malicious traffic across the network.", + "DECEPTIVE_BYTES": "Ingest Deceptive Bytes alerts from its active endpoint-deception platform to surface attacker activity early.", + "GITHUB": "Ingest GitHub audit logs to monitor repository access, code changes and organization activity for source security.", + "UTMSTACK": "Ingest UTMStack's own SIEM and XDR telemetry to monitor platform health, internal activity and self-audit events.", + "NGINX": { + "name": "Nginx", + "description": "Ingest Nginx access and error logs to monitor web-serving activity, reverse-proxy traffic and client requests." + }, + "APACHE": { + "name": "Apache", + "description": "Ingest Apache HTTPD access and error logs to monitor web-serving activity and client requests." + }, + "APACHE2": { + "name": "Apache2", + "description": "Ingest Apache2 (HTTPD) web server logs to monitor request handling, errors and access on Linux hosts." + }, + "IIS": { + "name": "IIS", + "description": "Ingest Internet Information Services (IIS) access and log-file activity to monitor Windows web serving." + }, + "MYSQL": { + "name": "MySQL", + "description": "Ingest MySQL database log activity to monitor queries, authentication and data-store access." + }, + "POSTGRESQL": { + "name": "PostgreSQL", + "description": "Ingest PostgreSQL database logs to monitor queries, access and activity across your data stores." + }, + "MONGODB": { + "name": "MongoDB", + "description": "Ingest MongoDB log activity to monitor document-database access, queries and application behavior." + }, + "REDIS": { + "name": "Redis", + "description": "Ingest Redis log and telemetry activity to monitor in-memory data store usage and real-time workloads." + }, + "ELASTICSEARCH": { + "name": "Elasticsearch", + "description": "Ingest Elasticsearch logs to monitor the search and analytics engine and its application workloads." + }, + "LOGSTASH": { + "name": "Logstash", + "description": "Ingest Logstash pipeline logs to monitor the data-processing pipeline and its event transformations." + }, + "KIBANA": { + "name": "Kibana", + "description": "Ingest Kibana logs to monitor the data-visualization and exploration layer and its usage." + }, + "KAFKA": { + "name": "Apache Kafka", + "description": "Ingest Apache Kafka logs to monitor real-time streaming pipelines, brokers and message flow." + }, + "NATS": { + "name": "NATS", + "description": "Ingest NATS messaging logs to monitor the message bus, connectivity and event delivery." + }, + "HAPROXY": { + "name": "HAProxy", + "description": "Ingest HAProxy logs to monitor load balancing, proxy traffic and network availability." + }, + "TRAEFIK": { + "name": "Traefik", + "description": "Ingest Traefik logs to monitor routing, load balancing and proxy traffic across workloads." + }, + "OSQUERY": { + "name": "osquery", + "description": "Ingest OsQuery logs to monitor endpoint state, queries and system inventory via SQL-style requests." + }, + "SYSLOG": { + "name": "Syslog", + "description": "Send syslog (RFC 5424/3164) from any device or application to the collector endpoint for central log intake." + }, + "JSON": { + "name": "JSON Input", + "description": "Send JSON log payloads to the ingestion endpoint for structured event intake from applications and scripts." + }, + "WINDOWS_SQL_SERVER": { + "name": "SQL Server Event Logs", + "description": "Collect Microsoft SQL Server audit and event records through the Windows Event Log and UTMStack agent." + }, + "WINDOWS_FILE_AUDITING": { + "name": "Windows File Access Auditing", + "description": "Collect Windows file access audit events through the Windows Event Log and UTMStack agent." + }, + "ELASTICsearch": { + "name": "ELASTICsearch", + "description": "Ingesta los registros de Elasticsearch para monitorear el motor de búsqueda y análisis y sus cargas de trabajo de aplicación." + } + }, + "edit": { + "title": "Edit integration" + }, + "allCategories": "All categories", + "customOnly": "Custom" + }, + "dataProcessing": { + "title": "Data processing", + "subtitle": "Ingestion and processing statistics: events received, dropped by stage, and the top sources and types.", + "ingestion": { + "title": "Ingestion", + "last24h": "last 24 hours", + "noData": "No data in this window.", + "loadError": "Could not load ingestion stats.", + "groupBy": { + "dataSource": "By data source", + "dataType": "By data type" + }, + "status": { + "received": "Received", + "parsing_dropped": "Dropped (parsing)", + "analysis_dropped": "Dropped (analysis)", + "correlation_dropped": "Dropped (correlation)", + "all": "All events" + } + }, + "filters": { + "title": "Filters", + "new": "New filter", + "search": "Search by path…", + "refresh": "Refresh", + "retry": "Retry", + "empty": "No filters match.", + "loadError": "Could not load filters.", + "toggleError": "Could not change the filter state", + "system": "System", + "custom": "Custom", + "systemReadonly": "System filters are read-only", + "view": "View", + "edit": "Edit", + "ownership": { + "all": "All", + "system": "System", + "custom": "Custom" + }, + "state": { + "all": "All", + "active": "Active", + "inactive": "Inactive" + }, + "col": { + "filter": "Filter", + "type": "Type", + "active": "Active", + "actions": "Actions" + }, + "pageInfo": "{{from}}–{{to}} of {{count}}" + }, + "editor": { + "createTitle": "New filter", + "editTitle": "Edit filter", + "viewTitle": "View filter", + "relPath": "Path", + "relPathHint": "Folder + file, e.g. syslog/my-filter.yaml", + "content": "Pipeline (YAML)", + "contentHint": "Steps run in order: grok, rename, delete, dynamic plugins, …", + "save": "Save", + "saving": "Saving…", + "saved": "Filter saved", + "saveError": "Could not save the filter", + "cancel": "Cancel", + "delete": "Delete", + "deleteConfirm": "Delete this filter?", + "deleted": "Filter deleted", + "deleteError": "Could not delete the filter" + }, + "kpi": { + "received": "Received", + "dropped": "Dropped", + "dropRate": "{{rate}}% drop rate", + "stored": "Stored", + "throughput": "Throughput", + "perMin": "{{value}}/min", + "survival": "{{rate}}% kept" + }, + "section": { + "overTime": "Events over time", + "top": "Top", + "dropReasons": "Drop reasons" + }, + "live": { + "auto": "Auto" + }, + "pipeline": { + "title": "Ingestion pipeline", + "stages": { + "received": "Received", + "parsed": "Parsed", + "analyzed": "Analyzed", + "stored": "Stored" + } + }, + "chart": { + "title": "Throughput over time", + "received": "Received", + "dropped": "Dropped" + }, + "donut": { + "title": "Drop composition", + "dropped": "dropped" + }, + "breakdown": { + "title": "Top sources & types", + "bars": "Bars", + "treemap": "Treemap", + "showAll": "Show all {{count}}", + "showLess": "Show less", + "lastSeen": "Last seen", + "ago": "{{time}} ago" + } }, - "empty": { - "title": "No dashboards yet", - "body": "Create your first dashboard to see your security data at a glance.", - "cta": "Create dashboard" + "datasources": { + "limitBanner": { + "title": "Datasource limit exceeded.", + "message": "You have {{count}} datasources but your license covers {{limit}}. Logs from datasources beyond the limit are being dropped.", + "cta": "Manage license", + "dismiss": "Dismiss" + }, + "title": "Data sources", + "total": "{{count}} total", + "subtitle": "Agents, integrations and direct sources feeding events. Status is derived from the last time each source was seen.", + "connectSource": "Connect a source", + "loading": "Loading data sources…", + "loadFailed": "Could not load data sources.", + "retry": "Retry", + "none": "No data sources match this view.", + "ingestion": { + "title": "Ingestion", + "received": "events received", + "none": "No ingestion in the last 24 hours.", + "ago24h": "24h ago", + "now": "now" + }, + "usage": { + "title": "Data sources", + "ofUnlimited": "of unlimited", + "ofLimit": "of {{limit}}", + "overLimit": "Over the licensed limit — data beyond the cap is at risk.", + "configured": "configured" + }, + "tabs": { + "all": "All", + "agent": "Agents", + "puller": "Integrations", + "direct": "Direct", + "offline": "Offline" + }, + "toolbar": { + "searchPlaceholder": "Search by name…", + "list": "List", + "cards": "Cards", + "refresh": "Refresh" + }, + "labels": { + "filteredBy": "Filtered by label", + "add": "Add label…", + "addFirst": "Add a label…", + "hint": "Type a label and press Enter to add it. Changes save automatically." + }, + "status": { + "live": "Live", + "idle": "Idle", + "offline": "Offline" + }, + "kind": { + "agent": "Agent", + "puller": "Integration", + "direct": "Direct" + }, + "cols": { + "source": "Source", + "type": "Type", + "status": "Status", + "events24h": "Events 24h", + "lastSeen": "Last seen" + }, + "time": { + "justNow": "just now", + "minutesAgo": "{{count}}m ago", + "hoursAgo": "{{count}}h ago", + "daysAgo": "{{count}}d ago" + }, + "drawer": { + "loading": "Loading…", + "loadFailed": "Could not load the data source.", + "statsIdentity": "Stats & identity", + "metadata": "Metadata", + "labelsSection": "Labels", + "dangerZone": "Danger zone", + "rows": { + "events24h": "Events 24h", + "lastSeen": "Last seen", + "discovered": "Discovered", + "kind": "Kind", + "dataType": "Data type", + "ip": "IP", + "id": "ID" + }, + "dangerText": "Deleting removes this source from the registry. Historical events stay searchable in the Log Explorer; if the source keeps sending data it will be rediscovered.", + "delete": "Delete data source", + "confirmDelete": "Confirm delete", + "cancel": "Cancel", + "viewLogs": "View logs", + "trend": "Ingestion trend", + "noTrend": "No events received in this window", + "logGap": "Last event {{since}} — possible log gap" + }, + "toast": { + "labelsUpdated": "Labels updated", + "labelsFailed": "Failed to update labels", + "deleted": "Data source deleted", + "deleteFailed": "Failed to delete" + }, + "console": { + "section": "Console", + "sectionHint": "Run commands on this host through its agent (live response).", + "open": "Open console", + "close": "Close", + "hint": "Type a command and press Enter to run it on the agent.", + "running": "Running…", + "placeholder": "Type a command…", + "offline": "This agent appears offline — it may not respond to commands.", + "vars": { + "button": "Variables", + "title": "Command variables", + "subtitle": "Reference these in commands as", + "add": "New variable", + "name": "Name", + "value": "Value", + "description": "Description", + "isSecret": "Secret (encrypted, masked in output)", + "secret": "secret", + "secretHint": "Leave blank to keep the stored value.", + "save": "Save", + "cancel": "Cancel", + "edit": "Edit", + "delete": "Delete", + "loading": "Loading…", + "empty": "No variables yet.", + "saved": "Variable saved", + "deleted": "Variable deleted", + "nameRequired": "Name is required", + "loadError": "Failed to load variables", + "saveError": "Failed to save variable", + "deleteError": "Failed to delete variable", + "insert": "Insert", + "valueRequired": "A value is required" + }, + "disabled": "Agent offline — commands are disabled", + "connError": "Connection error", + "cmdError": "Command error", + "shellSelect": "Shell type", + "noRemoteControl": "This agent was installed with remote control disabled. It refuses commands, and that can only be changed on the machine itself.", + "noRemoteControlShort": "Remote control disabled on this agent", + "password": { + "title": "Authentication", + "hint": "Authenticate to run commands on this agent.", + "tfaPrompt": "Code: ", + "confirm": "OK", + "cancel": "Cancel", + "authError": "Authentication failed", + "authHint": "Authenticate to run commands on this agent.", + "authOk": "Authenticated." + } + }, + "sensitivity": { + "section": "Asset sensitivity", + "hint": "Business criticality (CIA, 0–3) of this asset. Alerts targeting its host/IP are weighted by these values.", + "saved": "Sensitivity updated", + "failed": "Failed to update sensitivity", + "save": "Save", + "confidentiality": "Confidentiality", + "integrity": "Integrity", + "availability": "Availability", + "levels": { + "0": "None", + "1": "Low", + "2": "Medium", + "3": "High" + } + }, + "health": { + "online": "online", + "offline": "offline", + "total": "total" + } }, - "duplicate": { - "copyName": "{{name}} (copy)" - } - }, - "settings": { - "title": "Settings", - "license": "License", - "notifications": "Notifications", - "connectionKey": "Connection Key", - "dataRetention": "Data Retention", - "indices": "Indices", - "theme": "Theme", - "branding": "Branding", - "apiKeys": "API Keys", - "identityProviders": "Identity Providers", - "email": "Email Configuration", - "dateFormat": "Date Format", - "language": "Language", - "auditLogs": "App Audit Logs", - "about": "About", - "socAi": "SOC-AI", - "supportAccess": "Support access", - "threatwinds": "ThreatWinds Integration" - }, - "topbar": { - "theme": { - "light": "Light mode", - "dark": "Dark mode" + "adversaries": { + "title": "Adversary view", + "subtitle": "Every IP, host or user seen attacking your environment, with their techniques and targets.", + "countChip": "{{count}} adversaries", + "refresh": "Refresh", + "search": "Search by IP, host, user, country, ASO…", + "empty": "No adversaries match.", + "loadError": "Could not load adversaries.", + "retry": "Retry", + "views": { + "all": "All", + "high": "High severity", + "ip": "IPs", + "host": "Hosts", + "user": "Users" + }, + "threat": { + "critical": "Critical", + "high": "High", + "medium": "Medium", + "low": "Low" + }, + "kind": { + "ip": "IP", + "host": "Host", + "user": "User" + }, + "layout": { + "list": "List", + "cards": "Cards" + }, + "overview": { + "title": "Adversary activity · last 24 hours", + "high": "high severity", + "countries": "countries", + "alerts": "alerts", + "ago24": "24h ago", + "ago12": "12h ago", + "now": "now" + }, + "col": { + "adversary": "Adversary", + "threat": "Threat", + "alerts": "Alerts", + "targets": "Targets", + "lastSeen": "Last seen", + "victims": "Victims" + }, + "card": { + "alerts": "Alerts", + "techniques": "Techniques", + "targets": "Targets" + }, + "tabs": { + "profile": "Profile", + "techniques": "Techniques", + "targets": "Targets", + "alerts": "Alerts" + }, + "drawer": { + "activity": "Activity over 24 hours", + "identification": "Identification", + "kindLabel": "Type", + "identifier": "Identifier", + "firstSeen": "First seen", + "lastSeen": "Last seen", + "geolocation": "Geolocation", + "country": "Country", + "city": "City", + "topTechniques": "Top techniques", + "noTechniques": "No techniques recorded.", + "targets": "Targets", + "noTargets": "No targets recorded.", + "recentAlerts": "Recent alerts", + "noAlerts": "No alerts.", + "echoes": "{{count}} echoes" + }, + "relative": { + "justNow": "just now", + "minutesAgo": "{{count}}m ago", + "hoursAgo": "{{count}}h ago", + "daysAgo": "{{count}}d ago" + }, + "field": { + "ip": "IP", + "host": "Host", + "user": "User", + "port": "Port", + "domain": "Domain", + "mac": "MAC", + "country": "Country", + "city": "City", + "asn": "ASN", + "aso": "ASO" + } }, - "manageLicense": "Manage license", - "profile": { - "profile": "Profile", - "license": "License", - "logout": "Log out" - } - }, - "threatIntel": { - "header": { - "matchedInEnv": "matched in your env", - "export": "Export IOCs", - "exporting": "Exporting…", - "noInstanceIocs": "No instance indicators — showing generic data", - "noInstanceIocsHint": "No indicators observed in your alerts — showing generic feed data." + "timeRange": { + "quick": "Quick ranges", + "relative": "Relative", + "absolute": "Absolute", + "last": "Last", + "apply": "Apply", + "allTime": "All time", + "from": "From", + "to": "To", + "now": "now", + "units": { + "minutes": "minutes", + "hours": "hours", + "days": "days", + "weeks": "weeks", + "months": "months" + }, + "presets": { + "15m": "Last 15 minutes", + "1h": "Last 1 hour", + "6h": "Last 6 hours", + "24h": "Last 24 hours", + "7d": "Last 7 days", + "30d": "Last 30 days" + } }, - "overview": { - "title": "IOC matches", - "totalIndicators": "total indicators", - "families": { - "ip": "IP", - "url": "URL", - "domain": "Domain", - "signatures": "Signatures" - } - }, - "notConfigured": { - "title": "Threat Intelligence isn't configured", - "body": "Contact your administrator to connect an upstream Cyber Mantra / ThreatWinds instance for this environment." - }, - "lookup": { - "title": "Lookup any indicator", - "placeholder": "Paste an IP, domain, hash, URL, or CVE — we'll check feeds and your environment", - "button": "Lookup", - "busy": "Searching…" - }, - "tabs": { - "iocs": "IOCs", - "actors": "Threat actors", - "feeds": "Feeds", - "analyst": "AI Analyst" - }, - "toolbar": { - "searchPlaceholders": { - "iocs": "Search IOC value, tag, source…", - "actors": "Search actors, aliases, techniques…", - "feeds": "Search feeds…" - }, - "last24h": "Last 24 hours", - "filters": "Filters", - "refresh": "Refresh" - }, - "iocs": { - "table": { - "type": "Type", - "indicator": "Indicator", - "reputation": "Reputation", - "tags": "Tags", - "lastSeen": "Last seen" - }, - "empty": "No IOCs match.", - "loadingMore": "Loading more…", - "loadedProgress": "Loaded {{loaded}} of {{total}}. Scroll for more.", - "endOfResults": "End of results ({{loaded}} of {{total}})." - }, - "drawer": { - "loading": "Loading…", - "accuracy": "Accuracy:", - "actions": { - "block": "Block at perimeter", - "viewEvents": "View matched events", - "externalLookup": "External lookup", - "trackCampaign": "Track campaign", - "viewIocs": "View matched IOCs", - "mitre": "MITRE ATT&CK" - }, - "sections": { - "timeline": "Timeline", - "networkOrigin": "Network / origin", - "associationsWithCount": "Associations ({{count}})", - "geolocationsWithCount": "Geolocations ({{count}})", - "about": "About", - "activity": "Activity" - }, - "fields": { - "firstSeen": "First seen", - "lastSeen": "Last seen", - "country": "Country", - "city": "City", - "aso": "ASO", - "asn": "ASN", - "reputation": "Reputation", - "accuracy": "Accuracy", - "current": "Current", - "best": "Best", - "worst": "Worst" - }, - "aiBrief": "AI brief", - "noDescription": "No description available for this indicator.", - "lastObserved": "Last observed {{when}}." - }, - "actors": { - "empty": "No actors found." - }, - "feeds": { - "empty": "No feeds configured.", - "table": { - "name": "Feed", - "type": "Type", - "accuracy": "Accuracy", - "header": "Feeds", - "format": "Format" - }, - "download": "Download feed", - "checksum": "Checksum" - }, - "entityTypes": { - "ip": "IP", - "hostname": "Host", - "domain": "Domain", - "url": "URL", - "hash": "Hash", - "cve": "CVE", - "threat": "Threat", - "entity": "Entity" - }, - "reputation": { - "alarming": "Alarming", - "suspicious": "Suspicious", - "indefinable": "Indefinable", - "fair": "Fair", - "trustworthy": "Trustworthy" - }, - "feedAccuracy": { - "level1": "Level 1", - "level2": "Level 2", - "level3": "Level 3" - }, - "triage": { - "title": "Triage", - "subtitle": "Paste indicators, get verdicts", - "input": "Indicators", - "placeholder": "Paste IPs, domains, URLs or hashes — one per line, or comma separated.\nDefanged values (1.2.3[.]4, hxxp://) are accepted.", - "run": "Triage", - "stop": "Stop", - "reset": "Clear", - "parsed": "{{count}} unique indicators", - "capped": "Capped at {{max}} per run.", - "progress": "{{done}} of {{total}}", - "empty": "Paste indicators above to begin.", - "indicator": "Indicator", - "type": "Type", - "verdict": "Verdict", - "reputation": "Rep", - "accuracy": "Acc", - "tags": "Tags", - "lastSeen": "Last seen", - "exportCsv": "Export CSV", - "exportStix": "Export STIX", - "stixNote": "STIX export includes malicious and suspicious rows only.", - "open": "Open", - "notConfigured": "Threat intelligence is not configured — triage needs an upstream ThreatWinds instance.", - "v.malicious": "Malicious", - "v.suspicious": "Suspicious", - "v.benign": "Benign", - "v.unknown": "Unknown", - "v.notFound": "Not found", - "v.invalid": "Unrecognised", - "summary": "Summary" - }, - "report": { - "title": "Report", - "subtitle": "Publish an indicator to the ThreatWinds graph", - "submit": "Report indicator", - "submitting": "Reporting…", - "error": { - "generic": "Could not submit the indicator. Try again." - }, - "value": { - "label": "Indicator", - "placeholder": "IP, domain, URL, hash or email address" - }, - "type": { - "label": "Type", - "placeholder": "Inferred from the value", - "inferred": "Inferred: {{type}}", - "inferenceFailed": "No type could be inferred from this value. Choose one from the list, or type it.", - "unknown": "“{{type}}” is not an entity type. Choose one from the list." - }, - "tags": { - "label": "Tags", - "placeholder": "phishing, credential-theft" - }, - "description": { - "label": "Notes" - }, - "reputation": { - "legend": "Reputation", - "hint": "Leave unset if you have not reached a verdict.", - "alarming": "Alarming", - "worrying": "Worrying", - "concerning": "Concerning", - "indefinable": "Indefinable", - "adequate": "Adequate", - "good": "Good", - "exceptional": "Exceptional" - }, - "associations": { - "legend": "Related indicators", - "add": "Add related indicator", - "remove": "Remove", - "valuePlaceholder": "Related value", - "typePlaceholder": "Type (optional)", - "modeLabel": "Relationship", - "mode": { - "association": "Related to", - "aggregation": "Part of" - }, - "visibilityConflict": "This shares no visibility group with the indicator above. The whole submission would be rejected." - }, - "attributes": { - "legend": "Details", - "hint": "Optional. Anything left blank is not submitted.", - "invalidHex": "Expected {{length}} hexadecimal characters.", - "invalidHexAny": "Expected hexadecimal characters only.", - "invalidNumber": "Expected a number." - }, - "correlate": { - "legend": "Correlate", - "hint": "Each ticked attribute is published as its own entity, linked to this one.", - "count_one": "Creates {{count}} linked entity.", - "count_other": "Creates {{count}} linked entities." - }, - "scan": { - "notice": "Reporting this also queues a scan of the target." - }, - "receipt": { - "title": "Submitted", - "noVerdict": "No verdict stated", - "skipped": "Not submitted, no type could be inferred", - "pending": "Waiting for the indicator to appear in the corpus…", - "live": "Live in the corpus — view entity", - "processing": "Still being processed. It will appear once ingestion catches up.", - "another": "Report another" - }, - "visibility": { - "legend": "Visible to" - }, - "example": "Try example" - } - }, - "notifications": { - "title": "Notifications", - "markAllRead": "Mark all read", - "empty": "You have no notifications.", - "viewAll": "View all", - "markRead": "Mark as read", - "markUnread": "Mark as unread", - "delete": "Delete", - "subtitle": "{{total}} total · {{unread}} unread", - "allCaughtUp": "All caught up.", - "loadFailed": "Could not load notifications." - }, - "pagination": { - "perPage": "Per page", - "pageOf": "Page {{page}} of {{total}}", - "previous": "Previous", - "next": "Next" - }, - "license": { - "title": "License", - "subtitle": "Your edition, capabilities, and license file.", - "loading": "Loading license…", - "loadError": "Could not load license information.", - "statusLabel": "Status", - "status": { - "community": "Community", - "active": "Active", - "expiring": "Expiring soon", - "expired": "Expired" - }, - "edition": "Edition", - "enterprise": "Enterprise", - "community": "Community", - "editionLine": "{{edition}} edition", - "datasourceLimit": "Datasource limit", - "unlimited": "Unlimited", - "mssp": "MSSP / multi-tenant", - "enabled": "Enabled", - "licenseType": "License type", - "instanceId": "Instance ID", - "enterpriseUnlocked": "Enterprise features unlocked", - "validUntil": "Valid until", - "noExpiry": "No expiry", - "timeRemaining": "Time remaining", - "expiredAgo": "Expired {{days}}d ago", - "daysShort": "{{days}}d", - "msspShort": "MSSP", - "communityEdition": "Community edition", - "communityBlurb": "Free and open-source. Upload an Enterprise license below to unlock multi-tenancy, SSO, higher datasource limits, and advanced compliance.", - "upgrade": "Upgrade to Enterprise", - "uploadTitle": "Upload a license", - "uploadBlurb": "Install or replace the signed LICENSE file. The server validates the signature and expiry before applying it. Admin only.", - "installLicense": "Install license", - "chooseFile": "Choose file", - "noFileSelected": "No file selected", - "toast": { - "installed": "License installed — {{edition}} edition.", - "adminRequired": "Administrator privileges are required to upload a license.", - "invalid": "Invalid or expired license file.", - "installFailed": "Could not install the license." - }, - "ingestLimit": "Ingest volume", - "notMetered": "Not metered", - "gbPerMonth": "{{gb}} GB/month" - }, - "audit": { - "title": "Audit log", - "subtitle": "Record of every security-relevant action.", - "totalEntries": "{{total}} total entries.", - "loadError": "Could not load audit log", - "stats": { - "totalEntries": "Total entries", - "acrossAllTime": "Across all time", - "successRate": "Success rate", - "failuresOnPage_one": "{{count}} failure on this page", - "failuresOnPage_other": "{{count}} failures on this page", - "topAction": "Top action", - "onPage": "{{count}} on this page", - "uniqueActors": "Unique actors", - "includingSystem": "Including system" - }, - "filters": { - "title": "Filters", - "clear": "Clear", - "last24h": "Last 24h", - "failuresOnly": "Failures only", - "authEvents": "Auth events", - "actionPrefix": "Action prefix", - "actionPlaceholder": "e.g. auth., user.update", - "status": "Status", - "any": "Any", - "resourceType": "Resource type", - "resourceTypePlaceholder": "user, alert…", - "resourceId": "Resource id", - "user": "User", - "userPlaceholder": "login…" - }, - "statusValue": { - "success": "Success", - "failure": "Failure" - }, - "table": { - "timestamp": "Timestamp", - "actor": "Actor", - "action": "Action", - "resource": "Resource", - "status": "Status", - "ip": "IP", - "loading": "Loading…", - "emptyTitle": "No audit entries match these filters.", - "emptyHint": "Try clearing filters or widening the date range.", - "system": "system", - "view": "View" - }, - "drawer": { - "entry": "entry #{{id}}", - "overview": "Overview", - "raw": "Raw JSON", - "error": "Error", - "actor": "Actor", - "resource": "Resource", - "ip": "IP", - "userAgent": "User agent", - "session": "Session", - "metadata": "Metadata", - "copy": "Copy", - "copied": "Copied", - "copyJson": "Copy JSON" - } - }, - "team": { - "title": "Team", - "subtitle": "Manage users and their roles.", - "tabs": { - "members": "Members", - "roles": "Roles & permissions" - }, - "toast": { - "rolesLoadFailed": "Could not load roles", - "userLoadFailed": "Could not load user", - "rolesUpdated": "Roles updated", - "userReactivated": "User reactivated", - "userDeactivated": "User deactivated", - "tfaReset": "Two-factor authentication reset", - "invitationSent": "Invitation sent", - "loginOrEmailInUse": "That login or email is already in use", - "invalidRequest": "Invalid request", - "noPermission": "You do not have permission to do that", - "userNotFound": "User not found", - "operationFailed": "Operation failed", - "emailInUse": "That email is already in use", - "roleCreated": "Role created", - "roleUpdated": "Role updated", - "roleDeleted": "Role deleted", - "roleNameInUse": "A role with that identifier already exists", - "roleImmutable": "System roles cannot be modified", - "permissionsLoadFailed": "Could not load permissions", - "localUserCreated": "Local user created" - }, - "members": { - "searchPlaceholder": "Search by name or email…", - "invite": "Invite user", - "colUser": "User", - "colRoles": "Roles", - "col2fa": "2FA", - "colStatus": "Status", - "loading": "Loading users…", - "loadFailed": "Could not load users.", - "retry": "Retry", - "noSearchMatch": "No users match your search.", - "none": "No users yet.", - "noRole": "none", - "on": "On", - "off": "Off", - "countLabel_one": "{{count}} user · page {{page}} of {{pages}}", - "countLabel_other": "{{count}} users · page {{page}} of {{pages}}", - "federated": "SSO" - }, - "status": { - "inactive": "Inactive", - "pendingPassword": "Pending password", - "active": "Active", - "pending": "Pending invite", - "suspended": "Suspended" - }, - "drawer": { - "createdBy": "created by {{actor}}", - "loading": "Loading…", - "profileTitle": "Profile", - "profileSubtitle": "Only the user can edit these — from their own profile.", - "name": "Name", - "username": "Username", - "email": "Email", - "language": "Language", - "accountTitle": "Account", - "status": "Status", - "statusActive": "Active", - "statusInactive": "Inactive", - "tfa": "2FA", - "tfaEnabled": "Enabled", - "tfaNotConfigured": "Not configured", - "resetTfa": "Reset", - "resetTfaHint": "Disable this user's 2FA so they can re-enroll at next login", - "resetTfaConfirmTitle": "Reset two-factor authentication?", - "resetTfaConfirmBody": "This disables 2FA for {{name}}. They'll sign in with just their password and can set it up again from their profile.", - "resetTfaConfirm": "Reset 2FA", - "pendingPasswordNote": "Still using the temporary password (invite not completed).", - "lastModified": "Last modified {{time}}", - "rolesTitle": "Roles", - "rolesSubtitle": "Roles grant module permissions. A user can hold more than one.", - "noRoleWarning": "No role assigned — the user will have no module access.", - "deactivate": "Deactivate", - "reactivate": "Reactivate", - "waitingInvite": "Waiting for the user to accept the invitation.", - "cancel": "Cancel", - "saving": "Saving…", - "saveRoles": "Save roles", - "created": "created {{time}}", - "pendingNote": "Invitation not accepted yet.", - "federatedNote": "Signs in through an identity provider." - }, - "invite": { - "title": "Invite user", - "description": "The account is created inactive. The user receives an email to set their password and activate it.", - "username": "Username", - "usernameHint": "At least 3 characters.", - "email": "Email", - "firstName": "First name", - "lastName": "Last name", - "roles": "Roles", - "cancel": "Cancel", - "sending": "Sending…", - "send": "Send invite", - "name": "Name", - "emailHint": "This is the address they sign in with.", - "localDescription": "The account is created with a password and activated immediately. No email is sent.", - "modeInvite": "Invite user", - "modeLocal": "Create local user", - "passwordLabel": "Password", - "passwordPlaceholder": "Set a strong password", - "localUserNote": "This user will not receive an email and will be automatically activated.", - "createLocal": "Create user", - "passwordRules": { - "length": "At least 8 characters", - "case": "At least one uppercase and one lowercase letter", - "special": "At least one special character" - }, - "emailInvalid": "Please enter a valid email address" - }, - "rolePicker": { - "none": "No roles available." - }, - "roles": { - "loading": "Loading roles…", - "loadFailed": "Could not load role permissions.", - "readonlyNote": "Roles and their permissions are defined by the system and are read-only. Assign them to users from the Members tab.", - "permissionsCount_one": "{{count}} permission", - "permissionsCount_other": "{{count}} permissions", - "modulesCount_one": "{{count}} module", - "modulesCount_other": "{{count}} modules", - "matrixTitle": "Permission matrix", - "matrixSubtitle": "What each role can do, by module.", - "permission": "Permission", - "systemNote": "System roles ship with the platform and cannot be edited. Roles you create belong to this tenant.", - "newRole": "New role", - "edit": "Edit", - "delete": "Delete", - "systemBadge": "System", - "createTitle": "New role", - "editTitle": "Edit role", - "editorSubtitle": "Pick what this role may do. A user can hold more than one role.", - "nameLabel": "Identifier", - "nameHint": "Used in code and in the API. ROLE_AUDITOR, for example.", - "displayNameLabel": "Display name", - "descriptionLabel": "Description", - "permissionsLabel": "Permissions", - "selectedCount": "{{count}} selected", - "toggleAll": "all", - "loadingPermissions": "Loading permissions…", - "save": "Save role", - "deleteConfirmTitle": "Delete this role?", - "deleteConfirmBody": "{{name}} will be removed. Users who hold only this role will be left without module access." - }, - "langDefault": "System default", - "relative": { - "justNow": "just now", - "minutesAgo": "{{count}}m ago", - "hoursAgo": "{{count}}h ago", - "daysAgo": "{{count}}d ago" - }, - "roleNames": { - "ROLE_ADMIN": "Administrator", - "ROLE_USER": "User" - }, - "roleDescriptions": { - "ROLE_ADMIN": "Full access to all resources", - "ROLE_USER": "Standard user with module-level read access" - }, - "actions": { - "read": "Read", - "write": "Write", - "delete": "Delete" - }, - "resources": { - "adaudit": "AD Audit", - "alerts": "Alerts", - "audit": "Audit log", - "compliance": "Compliance", - "config": "Configuration", - "dashboards": "Dashboards", - "datasources": "Datasources", - "eventprocessing": "Event processing", - "idp": "Identity providers", - "incidents": "Incidents", - "integrations": "Integrations", - "loganalyzer": "Log analyzer", - "opensearch": "OpenSearch", - "roles": "Roles", - "soar": "SOAR", - "users": "Users", - "notifications": "Notifications", - "socai": "SOC AI", - "tenant": "Tenants", - "threatintel": "Threat intelligence" - } - }, - "apiKeys": { - "title": "API keys", - "subtitle": "Programmatic access tokens for the UTMStack API.", - "new": "New API key", - "searchPlaceholder": "Search by name or allowed IP…", - "refresh": "Refresh", - "loading": "Loading API keys…", - "loadFailed": "Could not load API keys.", - "retry": "Retry", - "noSearchMatch": "No API keys match your search.", - "empty": "No API keys yet. Create one to get started.", - "anyIp": "Any IP", - "never": "Never", - "count_one": "{{count}} key · page {{page}} of {{pages}}", - "count_other": "{{count}} keys · page {{page}} of {{pages}}", - "enterprise": { - "title": "API keys are an Enterprise feature", - "body": "Issue, scope and rotate API keys for programmatic access to the UTMStack API. This capability is available on the Enterprise edition.", - "upgrade": "Upgrade to Enterprise", - "manageLicense": "Manage your license" - }, - "col": { - "name": "Name", - "allowedIps": "Allowed IPs", - "created": "Created", - "lastRotated": "Last rotated", - "expires": "Expires", - "status": "Status", - "actions": "Actions" - }, - "status": { - "active": "Active", - "expiring": "Expiring", - "expired": "Expired" - }, - "action": { - "rotate": "Rotate", - "edit": "Edit", - "delete": "Delete" - }, - "dialog": { - "editTitle": "Edit API key", - "newTitle": "New API key", - "name": "Name", - "namePlaceholder": "ci-pipeline", - "allowedIps": "Allowed IPs", - "allowedIpsHint": "Comma-separated. Leave empty to allow any IP.", - "expires": "Expires", - "expiresHint": "Leave empty for a key that never expires.", - "secretNote": "The secret token is shown once, right after creation. Copy it then — it can’t be retrieved later (only rotated).", - "cancel": "Cancel", - "saving": "Saving…", - "saveChanges": "Save changes", - "createKey": "Create key" - }, - "confirm": { - "deleteTitle": "Delete API key", - "rotateTitle": "Rotate API key", - "deleteBody": "Delete {{name}}? Any client using it will immediately lose access. This cannot be undone.", - "rotateBody": "Rotate {{name}}? A new secret is issued and the current one stops working immediately. The new token is shown once.", - "cancel": "Cancel", - "working": "Working…", - "delete": "Delete", - "rotate": "Rotate" - }, - "reveal": { - "title": "API key created", - "note": "Copy this secret now — for {{name}}. It won’t be shown again. If you lose it, rotate the key.", - "copied": "Copied", - "copy": "Copy", - "done": "Done" - }, - "toast": { - "updated": "API key updated", - "secretIssueFailed": "Key created, but the secret could not be issued. Use Rotate to get one.", - "deleted": "API key deleted" - }, - "error": { - "nameTaken": "An API key with that name already exists", - "enterpriseRequired": "API keys require the Enterprise edition", - "notFound": "API key not found", - "invalidRequest": "Invalid request", - "failed": "Operation failed" - } - }, - "idp": { - "title": "Identity Providers", - "subtitle": "SAML 2.0 single sign-on for your organization.", - "add": "Add provider", - "enterprise": { - "title": "SSO is an Enterprise feature", - "body": "Connect a SAML 2.0 identity provider (Entra ID, Okta, Google Workspace…) so your team signs in with your IdP. Single sign-on is available on the Enterprise edition.", - "upgrade": "Upgrade to Enterprise" - }, - "loading": "Loading identity providers…", - "loadFailed": "Could not load identity providers.", - "retry": "Retry", - "empty": { - "title": "No identity providers configured", - "body": "Add a SAML 2.0 provider to let your team sign in with your corporate IdP." - }, - "card": { - "enable": "Enable", - "disable": "Disable", - "active": "Active", - "disabled": "Disabled", - "metadataUrl": "Metadata URL", - "spEntityId": "SP Entity ID", - "spAcsUrl": "SP ACS URL", - "loginUrl": "Login URL", - "copy": "Copy", - "edit": "Edit", - "delete": "Delete", - "jit": "Provisioning", - "jitOn": "creates accounts on first sign-in", - "sync": "Roles", - "syncOn": "re-applied on every sign-in" - }, - "form": { - "addTitle": "Add identity provider", - "editTitle": "Edit identity provider", - "name": "Name", - "nameHint": "Unique. Used in the SSO URL.", - "providerType": "Provider type", - "providerTypeHint": "A label, e.g. azure, okta, google.", - "metadataUrl": "IdP metadata URL", - "spEntityId": "SP Entity ID", - "spAcsUrl": "SP ACS URL", - "certificate": "SP certificate (PEM)", - "privateKey": "SP private key (PEM)", - "privateKeyHintEdit": "Leave empty to keep the stored key.", - "privateKeyHintCreate": "Required. Stored encrypted; never shown again.", - "privateKeyUnchanged": "•••••••• (unchanged)", - "active": "Active (show on the login page)", - "cancel": "Cancel", - "saving": "Saving…", - "save": "Save changes", - "create": "Create provider", - "issuer": "Issuer URL", - "issuerHint": "Discovery runs against this; the provider must serve /.well-known/openid-configuration under it.", - "clientId": "Client ID", - "redirectUrl": "Redirect URL", - "redirectUrlHint": "Register this exact URL with the provider.", - "host": "Host", - "port": "Port", - "startTls": "TLS", - "startTlsOn": "Use StartTLS", - "bindDn": "Bind DN", - "bindDnHint": "A service account that may search the directory.", - "baseDn": "Base DN", - "userFilter": "User filter", - "userFilterHint": "Must contain %s, where the address typed at login is placed.", - "emailAttribute": "Email attribute", - "nameAttribute": "Name attribute", - "groupAttribute": "Group attribute", - "provisioning": "Accounts and roles", - "provisioningHint": "What happens when someone the directory vouches for signs in.", - "jit": "Create the account on first sign-in", - "defaultRole": "Default role", - "defaultRoleHint": "Given when no group matches. Without one, an unmatched sign-in is refused.", - "noDefaultRole": "None", - "groupsAttribute": "Groups attribute", - "groupsAttributeHint": "Where the provider puts group membership.", - "syncRoles": "Re-apply roles on every sign-in", - "syncRolesHint": "Roles not in the mapping are removed, so a change in the directory reaches here. Without this, a demotion never arrives.", - "mappings": "Group to role", - "mappingsHint": "A directory group on the left, the role it grants on the right.", - "addMapping": "Add", - "noMappings": "No mappings. Everyone gets the default role.", - "groupPlaceholder": "SOC Analysts", - "pickRole": "Pick a role", - "secret.saml": "SP private key", - "secret.oidc": "Client secret", - "secret.ldap": "Bind password", - "secretHintCreate": "Stored encrypted and never shown again.", - "secretHintEdit": "Leave blank to keep the stored one.", - "secretUnchanged": "unchanged", - "errors": { - "required": "This field is required.", - "url": "Must be a valid http(s) URL.", - "httpsUrl": "Must be a valid https URL.", - "hostname": "Enter a host or IP without a scheme (e.g. ldap.example.com).", - "port": "Port must be a whole number between 0 and 65535.", - "pemCertificate": "Does not look like a PEM certificate (missing -----BEGIN/END CERTIFICATE-----).", - "pemKey": "Does not look like a PEM private key (missing -----BEGIN/END PRIVATE KEY-----).", - "userFilterPlaceholder": "The filter must contain %s, where the login address is placed.", - "userFilterUnbalanced": "Parentheses are unbalanced — the search will return nothing.", - "nameFormat": "Use letters, digits, dots, dashes or underscores (max 64). It appears in the SSO URL, so no spaces.", - "redirectUrl": "Must be a valid https URL, or an http loopback URL (localhost / 127.0.0.1 / [::1]).", - "entityId": "Must be a valid URI, e.g. https://utmstack.example.com/sp." - } - }, - "delete": { - "title": "Delete identity provider", - "body": "Delete {{name}}? Users will no longer be able to sign in through it. This cannot be undone.", - "cancel": "Cancel", - "deleting": "Deleting…", - "confirm": "Delete" - }, - "toast": { - "enabled": "Provider enabled", - "disabled": "Provider disabled", - "created": "Identity provider created", - "updated": "Identity provider updated", - "deleted": "Identity provider deleted", - "paidPlan": "SAML SSO requires a paid plan", - "enterpriseRequired": "SSO requires the Enterprise edition", - "notFound": "Identity provider not found", - "invalid": "Invalid configuration", - "failed": "Operation failed" - }, - "providerType": { - "saml": "SAML 2.0", - "oidc": "OpenID Connect", - "ldap": "LDAP / Active Directory", - "comingSoon": "not available yet" - } - }, - "userAuditor": { - "title": "User auditor", - "subtitle": "Active Directory accounts observed in your Windows security logs — discovered from create, logon and delete events.", - "export": "Export", - "accountsChip": "{{count}} accounts", - "overview": { - "title": "Account inventory", - "active": "active", - "disabled": "disabled", - "deleted": "deleted", - "seen24h": "{{count}} seen in the last 24 hours", - "byDomain": "By domain" - }, - "views": { - "all": "All accounts", - "windows": "Windows", - "linux": "Linux", - "active": "Active", - "disabled": "Disabled", - "deleted": "Deleted", - "service": "Service accounts", - "stale": "Stale (30d+)" - }, - "searchPlaceholder": "Search by account name or SID…", - "allTenants": "All tenants", - "filters": { - "add": "Add filter", - "clearAll": "Clear all", - "filterValues": "Filter values…", - "loadingValues": "Loading values…", - "noValues": "No values found.", - "pickValue": "Pick a value to add the filter.", - "empty": "(empty)", - "cancel": "Cancel", - "addBtn": "Add" - }, - "filterFields": { - "status": "Lifecycle status" - }, - "ops": { - "is": "is" - }, - "refresh": "Refresh", - "layout": { - "list": "List", - "cards": "Cards" - }, - "list": { - "account": "Account", - "identity": "Identity", - "sid": "SID", - "status": "Status", - "lastLogon": "Last logon", - "lastSeen": "Last seen", - "tenant": "Tenant" - }, - "status": { - "active": "Active", - "disabled": "Disabled", - "deleted": "Deleted" - }, - "badge": { - "service": "service", - "stale": "stale" - }, - "empty": "No accounts match this view.", - "loadError": "Could not load AD accounts.", - "retry": "Retry", - "card": { - "lastLogon": "Last logon" - }, - "pageInfo": "{{from}}–{{to}} of {{count}}", - "drawer": { - "tenantInline": "tenant {{id}}", - "serviceAccount": "service account", - "stale": "stale 30d+", - "viewInLogs": "View events in Log Explorer", - "copySid": "Copy SID", - "copyUid": "Copy identity", - "copied": "Copied", - "identity": "Identity", - "accountName": "Account name", - "domain": "Domain", - "hostname": "Hostname", - "sid": "SID", - "uidNumber": "UID", - "machineId": "Machine ID", - "tenant": "Tenant", - "adStatus": "AD status", - "enabled": "Enabled", - "disabled": "Disabled", - "lifecycle": "Lifecycle", - "created": "Account created", - "lastLogon": "Last logon", - "lastSeen": "Last seen in logs", - "deleted": "Account deleted", - "noLifecycle": "No lifecycle events recorded." - }, - "relative": { - "justNow": "just now", - "minutesAgo": "{{count}}m ago", - "hoursAgo": "{{count}}h ago", - "daysAgo": "{{count}}d ago" - }, - "none": "—" - }, - "connectionKey": { - "title": "Connection key", - "subtitle1": "The key agents present when they register with this instance.", - "subtitleEmphasis": "It is only used for agent installation", - "subtitle2": "— not for collectors, integrations, or the API. It is managed by the agent-manager.", - "status": { - "label": "Status", - "loading": "Loading…", - "unavailable": "Agent-manager unavailable", - "active": "Active", - "unavailableHint": "Could not reach the agent-manager to read the key.", - "activeHint": "Agents can register using this key." - }, - "token": { - "title": "Connection key", - "subtitle": "Treat this value as a credential. Rotating it issues a new key for future agent installations — agents already registered keep working.", - "loadFailedTitle": "Couldn’t load the connection key", - "unavailableTitle": "Connection key unavailable", - "loadFailedHint": "The key is managed by the agent-manager, which didn’t respond. Try again in a moment.", - "retry": "Retry", - "show": "Show key", - "hide": "Hide key", - "copy": "Copy", - "copied": "Copied", - "regenerate": "Regenerate connection key", - "confirmTitle": "Regenerate the key?", - "confirmBody": "New agent installations will need the new key. Agents already registered keep working. There's no undo.", - "regenerating": "Regenerating…", - "confirmYes": "Yes, regenerate", - "cancel": "Cancel" - }, - "security": { - "title": "Security recommendations", - "subtitle": "Best practices for protecting this credential.", - "rotateTitle": "Rotate every 90 days", - "rotateBody": "Schedule a recurring rotation. UTMStack can email you a reminder when the key is older than 90 days.", - "rotateAction": "Set up reminder", - "secretTitle": "Store as a secret", - "secretBody": "Don't commit the key to source control. Use your secret manager (Vault, AWS SM, etc.) and inject it at install time.", - "auditTitle": "Audit who fetched it", - "auditBody": "Every fetch and rotation is recorded in the application audit log.", - "auditAction": "View audit log" - }, - "toast": { - "loadFailed": "Could not load connection key", - "rotated": "Connection key rotated", - "rotateFailed": "Could not rotate connection key", - "copyFailed": "Could not copy" - } - }, - "dataRetention": { - "title": "Data retention", - "subtitle": "How long each dataset is kept, and when its records stop costing local disk.", - "loading": "Loading…", - "loadFailed": "Could not read the store.", - "retry": "Retry", - "datasets": { - "logs": "Logs", - "alerts": "Alerts", - "statistics": "Ingestion statistics" - }, - "holding": "{{documents}} records · {{size}}", - "since": "since {{date}}", - "diskUsed": "Disk {{pct}}% used", - "keep": "Delete after", - "keepHint": "A record is deleted this many days after it happened, wherever it is stored by then.", - "cold": "Move to cold storage after", - "coldHint": "Older records move to object storage and stay queryable. 0 keeps everything on local disk.", - "coldUnavailable": "Set up cold storage below to move older records off local disk.", - "coldBeforeDelete": "Records have to move before they are deleted: use fewer days than the lifetime, or 0.", - "tieredNote": "This dataset moves records to cold storage. Going back to local-only needs the table rebuilt, so it cannot be turned off here.", - "days": "days", - "save": "Save", - "saving": "Saving…", - "toast": { - "saved": "Retention saved", - "noPermission": "You do not have permission to change retention", - "saveFailed": "Could not save the retention" - }, - "coldStorage": { - "title": "Cold storage", - "hint": "An object store the event store treats as a second, slower disk. Older records move there and are still queried from the same place — it is not an archive and nothing has to be restored.", - "active": "In use", - "inactive": "Not set up", - "writtenNotReady": "The bucket is configured but the store has not picked it up. Check that the deployment shares the store's configuration directory.", - "endpoint": "Bucket URL", - "accessKey": "Access key", - "secretKey": "Secret key", - "bucketLocked": "The credentials can be changed at any time. The bucket cannot, once records live in it: the parts already moved carry it.", - "enable": "Enable cold storage", - "update": "Update credentials", - "toast": { - "saved": "Cold storage configured", - "failed": "Could not configure cold storage" - }, - "kind": "Type", - "kind_s3": "S3-compatible object store", - "kind_local": "Local folder or NFS", - "kind_azure": "Azure Blob Storage", - "accountUrl": "Storage account URL", - "container": "Container", - "accountName": "Account name", - "accountKey": "Account key", - "useRole": "Use the server's IAM role instead of keys", - "s3Hint": "Works with AWS S3 and any S3-compatible store: MinIO, Ceph, Wasabi, Cloudflare R2, or Google Cloud Storage (endpoint https://storage.googleapis.com// with HMAC keys).", - "localHint": "Records move to the folder mounted at /mnt/utmstack-cold inside the event store: a plain directory in the data folder, or an NFS share mounted over /clickhouse/cold on the host before the stack starts. No credentials needed.", - "changeWarning": "Records already moved to the current destination are not migrated. They stay there and stop being readable from here until the old destination is copied across by hand." - }, - "forbidden": { - "title": "This page belongs to the platform", - "body": "Retention applies to the tables every tenant shares, so only a platform administrator can read or change it. Ask one, or sign in with a platform account." - } - }, - "languageSettings": { - "title": "Platform language", - "subtitle": "Default UI language for pre-login screens, system emails and new users. Each user can still pick their own in their profile.", - "label": "Default language", - "hint": "Used when a user hasn't chosen their own language.", - "save": "Save", - "saving": "Saving…", - "saved": "Platform language updated", - "loadError": "Could not load the language setting", - "saveError": "Could not save the language setting" - }, - "branding": { - "title": "Branding", - "subtitle": "White-label UTMStack with your organization’s identity — applied everywhere: the login screen, sidebar, emails and reports.", - "enterpriseRequired": "White-labeling is an Enterprise feature.", - "manageLicense": "Manage license", - "enable": { - "title": "White-label", - "description": "Replace the UTMStack brand with your own across the platform.", - "label": "Enable white-labeling" - }, - "identity": { - "title": "Identity", - "productName": "Product name", - "productNameHint": "Shown in the title bar, sidebar and emails.", - "accent": "Accent color", - "accentHint": "Primary color for buttons, links and active states.", - "custom": "Custom color" - }, - "logos": { - "title": "Logos", - "hint": "PNG, SVG, WEBP, JPG or ICO. Up to 5 MB.", - "logo": "Logo (light)", - "logoDark": "Logo (dark)", - "favicon": "Favicon" - }, - "reports": { - "title": "Report assets", - "hint": "Embedded in generated PDF reports.", - "reportLogo": "Report logo", - "reportCover": "Report cover" - }, - "asset": { - "upload": "Upload", - "replace": "Replace" - }, - "save": "Save changes", - "saving": "Saving…", - "saved": "Branding updated", - "saveError": "Could not save branding", - "uploaded": "Image uploaded", - "uploadError": "Could not upload image", - "loadError": "Could not load branding", - "enterprise": { - "title": "White-labelling is an Enterprise feature", - "body": "Replace the product name, logo and report cover with your own, so the panel and everything it generates carry your brand instead of UTMStack's.", - "upgrade": "Upgrade to Enterprise" - }, - "restore": "Restore UTMStack defaults", - "restored": "Branding restored to the UTMStack defaults" - }, - "emailConfig": { - "title": "Email configuration", - "subtitle": "SMTP server used to send alert notifications, reports and account emails.", - "server": { - "title": "SMTP server", - "host": "Host", - "hostHint": "Hostname of your SMTP server.", - "port": "Port", - "encryption": "Encryption", - "username": "Username", - "password": "Password", - "passwordSetHint": "A password is saved. Leave blank to keep it, or type a new one to change it." - }, - "encryptionOpt": { - "TLS": "TLS", - "SSL": "SSL", - "NONE": "None" - }, - "sender": { - "title": "Sender", - "from": "From address", - "fromHint": "Address emails are sent from.", - "organization": "Organization name", - "organizationHint": "Shown in alert and incident notification emails.", - "baseUrl": "Base URL", - "baseUrlHint": "Public URL of this instance, used for links in emails." - }, - "test": { - "button": "Send test", - "sending": "Sending…", - "sentTo": "A test email will be sent to {{email}}.", - "success": "Test email sent to {{email}}", - "fail": "Could not send the test email", - "fromRequired": "Set a From address before testing" - }, - "save": "Save changes", - "saving": "Saving…", - "saved": "Email configuration saved", - "saveError": "Could not save the configuration", - "loadError": "Could not load the configuration", - "recipients": { - "alertsTitle": "Alert recipients", - "incidentsTitle": "Incident recipients", - "to": "To", - "cc": "CC", - "alertsHelper": "Addresses notified when new alerts are raised. Leave empty and alerts are not emailed.", - "incidentsHelper": "Addresses notified when an incident is created. Leave empty and incidents are not emailed.", - "add": "Add" - } - }, - "dateFormat": { - "title": "Date & time", - "subtitle": "How timestamps are displayed across the platform. Logs are always stored in UTC.", - "timezone": { - "title": "Time zone", - "hint": "Timestamps are shown in this time zone. Stored data stays in UTC.", - "system": "Browser default", - "now": "Now: {{value}}" - }, - "format": { - "title": "Date format", - "hint": "Style used for dates and times." - }, - "styles": { - "short": "Short", - "medium": "Medium", - "long": "Long", - "full": "Full" - }, - "save": "Save changes", - "saving": "Saving…", - "saved": "Date settings saved", - "saveError": "Could not save the settings", - "loadError": "Could not load the settings" - }, - "about": { - "title": "About this instance", - "subtitle": "Version, license, and system health for this UTMStack deployment.", - "loading": "Loading instance information…", - "edition": { - "enterprise": "Enterprise", - "community": "Community" - }, - "fields": { - "hostname": "Server", - "instanceId": "Instance ID", - "noInstanceMeta": "No instance metadata available." - }, - "license": { - "title": "License", - "enterpriseMssp": "Enterprise · MSSP", - "datasources": "Datasources", - "communityLimited": "Community limit", - "unlimited": "Unlimited", - "expires": "Expires", - "managedNote": "Edition, datasource limits and license upload are managed on the License page.", - "view": "View license", - "ingest": "Ingest volume", - "notMetered": "Not metered", - "gbPerMonth": "{{gb}} GB/month" - }, - "services": { - "backend": { - "name": "Backend API", - "desc": "REST gateway, auth and module orchestration." - }, - "opensearch": { - "name": "OpenSearch", - "desc": "Log and event storage backend.", - "detail": "{{nodes}} nodes · {{shards}} shards" - }, - "unreachable": "Unreachable" - }, - "status": { - "up": "Healthy", - "degraded": "Degraded", - "down": "Down", - "unknown": "Unknown" - }, - "health": { - "title": "System health", - "allHealthy": "All services healthy. Refresh to recheck.", - "issues_one": "{{count}} service needs attention.", - "issues_other": "{{count}} services need attention.", - "refresh": "Refresh" - }, - "usage": { - "title": "Data sources", - "subtitle": "Data sources configured in this deployment.", - "ofUnlimited": "of unlimited", - "ofLimit": "of {{limit}}", - "overLimit": "Over the licensed limit — data beyond the cap is at risk.", - "configured": "configured" - }, - "support": { - "title": "Support", - "docs": "Documentation", - "repo": "GitHub repository", - "issues": "Report an issue", - "website": "utmstack.com" - }, - "legal": { - "title": "Legal", - "license": "License", - "security": "Security disclosure", - "copyright": "© {{year}} UTMStack. All rights reserved." - } - }, - "logExplorer": { - "title": "Log explorer", - "eventsIn": "events in", - "searching": "Searching…", - "query": { - "allDataTypes": "All data types", - "dataTypes": "Data types", - "exportCsv": "Export CSV", - "filterDataTypes": "Filter data types…", - "noDataTypes": "No data types", - "noDataTypesMatch": "No matching data types", - "noTextSearch": "This data source has no full-text field — filter by field instead", - "refresh": "Refresh", - "run": "Run", - "search": "Search", - "searchPlaceholder": "Search across all fields…" - }, - "time": { - "15m": "Last 15 minutes", - "1h": "Last 1 hour", - "6h": "Last 6 hours", - "24h": "Last 24 hours", - "7d": "Last 7 days", - "30d": "Last 30 days" - }, - "ops": { - "is": "is", - "isNot": "is not", - "contains": "contains", - "exists": "exists", - "between": "between", - "search": "search", - "isOneOf": "is one of", - "isNotOneOf": "is not one of", - "doesNotContain": "does not contain", - "startsWith": "starts with", - "doesNotStartWith": "does not start with", - "endsWith": "ends with", - "doesNotEndWith": "does not end with", - "doesNotExist": "does not exist", - "notBetween": "not between", - "greaterThan": "is greater than", - "greaterThanOrEquals": "is greater than or equal to", - "lessThan": "is less than", - "lessThanOrEquals": "is less than or equal to" - }, - "filters": { - "label": "Filters", - "clearAll": "Clear all" - }, - "fields": { - "title": "Fields", - "filterPlaceholder": "Filter fields…", - "none": "No fields", - "selected": "Selected fields", - "available": "Available fields", - "topValues_one": "Top {{count}} value", - "topValues_other": "Top {{count}} values", - "loading": "Loading…", - "noValues": "No values", - "addColumn": "Add as column", - "removeColumn": "Remove column from table", - "filterFor": "Filter for value", - "filterOut": "Filter out value", - "empty": "(empty)" - }, - "results": { - "dataTypesFailed": "Could not load data types.", - "endOfResults": "All {{count}} events loaded", - "loadingMore": "Loading more…", - "message": "Message", - "none": "No logs match this query.", - "removeColumn": "Remove {{field}}", - "retry": "Retry", - "searchFailed": "Search failed.", - "searching": "Searching…", - "source": "Source", - "time": "Time", - "scope": "Searched {{dataset}} · {{dataType}}.", - "searchAllDataTypes": "Search every data type" - }, - "detail": { - "fieldsCount_one": "{{count}} field", - "fieldsCount_other": "{{count}} fields", - "copyJson": "Copy JSON", - "copied": "Document copied", - "parsedFields": "Parsed fields", - "json": "JSON", - "filterFor": "Filter for", - "filterOut": "Filter out", - "surrounding": "Surrounding events", - "surroundingHint": "Show events ±15 min around this one, from the same source" - }, - "view": { - "table": "Table", - "chart": "Chart" - }, - "chart": { - "aggregateOn": "Aggregate on", - "per": "per", - "topValues": "— top 20 values", - "building": "Building chart…", - "failed": "Could not build the chart for this field.", - "noData": "No data to chart." - }, - "intervals": { - "minute": "Minute", - "hour": "Hour", - "day": "Day", - "week": "Week", - "month": "Month", - "quarter": "Quarter", - "year": "Year" - }, - "toast": { - "exportFailed": "Export failed" - }, - "builder": { - "add": "Add filter", - "filterValues": "Filter values…", - "loadingValues": "Loading values…", - "noValues": "No values found.", - "pickValue": "Pick a value to add the filter.", - "cancel": "Cancel", - "confirm": "Add" - }, - "related": { - "nLogs_one": "{{count}} log", - "nLogs_other": "{{count}} logs", - "truncated": "Showing the first {{count}} related logs (the full set is larger)." - }, - "saved": { - "title": "Saved", - "empty": "No saved searches yet", - "saveCurrent": "Save current search", - "save": "Save", - "namePlaceholder": "Search name", - "delete": "Delete", - "saved": "Saved “{{name}}”", - "loading": "Loading…", - "loadFailed": "Could not load saved searches", - "saveFailed": "Could not save the search", - "deleteFailed": "Could not delete the search", - "unreadable": "That saved search could not be read" - } - }, - "integrations": { - "title": "Integrations", - "searchPlaceholder": "Search integrations…", - "noMatch": "No integrations match.", - "browseMarketplace": "Browse marketplace", - "loading": "Loading integrations…", - "addCustom": { - "title": "Add custom integration", - "description": "Create a new custom source", - "cta": "Create" - }, - "tabs": { - "all": "All", - "agents": "Agents", - "collectors": "Collectors", - "cloud": "Cloud", - "custom": "Custom" - }, - "kind": { - "agents & syslog": "Agent", - "device": "Collector", - "antivirus": "Collector", - "other": "Collector", - "custom": "Custom", - "cloud": "Cloud", - "utmstack modules": "Collector" - }, - "status": { - "configured": "Configured", - "available": "Available" - }, - "card": { - "manage": "Manage →", - "setup": "Set up →", - "eventsPerSec": "{{rate}} e/s", - "enabled": "Enabled", - "setupShort": "Set up" - }, - "drawer": { - "manage": "Manage", - "openDashboard": "Open dashboard", - "viewEvents": "View events", - "documentation": "Documentation", - "getInstallCmd": "Get install command", - "setupCollector": "Set up collector", - "connect": "Connect", - "configureCustom": "Configure custom source", - "eventsRate": "{{rate}} events/sec · {{count}} in 24h", - "manageRules": "Rules", - "manageFilters": "Filters" - }, - "setup": { - "agent": { - "howItWorksTitle": "How it works", - "howItWorksBody": "The {{name}} agent is a small daemon that runs on the host and forwards local events to UTMStack over an authenticated TLS connection. It auto-updates and reports its health.", - "installTitle": "Install on {{name}}", - "installHint": "Run this command on every {{name}} host you want to monitor. The token already encodes your current workspace.", - "afterTitle": "What you'll see after install", - "after1": "The host appears under Data Sources within ~60 seconds of agent start.", - "after2": "Telemetry begins flowing into Log Explorer, scoped to your workspace.", - "after3": "The agent self-reports CPU / memory / disk health back to UTMStack.", - "actionLabel": "Action", - "platformLabel": "Platform", - "optionsLabel": "Options", - "skipCertValidation": "Skip TLS certificate validation (self-signed server)", - "noRemoteControl": "Disable remote command execution on this host", - "loadingToken": "Loading token…", - "actions": { - "install": "Install", - "uninstall": "Uninstall" - }, - "prereqTitle": "Pre-installation requirements", - "prereqBody": "The UTMStack agent communicates with the server over the following ports. Make sure they are open between the host and UTMStack before installing:", - "sensitiveWarning": "The command below contains a sensitive enrollment token — do not share it.", - "uninstall": { - "title": "Uninstall the agent", - "body": "Run this on the host to stop and remove the UTMStack agent and its services. It uses the platform selected above." - }, - "macCompat": "Requires macOS 11 (Big Sur) or later on Apple Silicon (M1/M2/M3 or newer). Intel-based Macs are not supported." - }, - "collector": { - "howItWorksTitle": "How it works", - "howItWorksBody": "{{name}} doesn't run a UTMStack agent. Instead, you install the UTMStack collector somewhere on the network that both your {{name}} device and UTMStack can reach. {{name}} sends syslog to the collector, the collector parses, normalizes, and forwards events into UTMStack.", - "step1Title": "1 · Install the UTMStack collector", - "step1Hint": "Run on a Linux host with network access from the {{name}} device.", - "step2Title": "2 · Configure {{name}} to send syslog", - "step2Hint": "On the {{name}} device, point syslog forwarding to the collector's address on {{port}}.", - "vendorDocs": "See vendor-specific instructions", - "step3Title": "3 · Verify", - "step3Body": "Within a few minutes you should see {{name}} events under source: {{source}} in Log Explorer, and a new entry in Data Sources.", - "endpoint": { - "title": "Connection details", - "hint": "Configure {{name}} to forward its logs to the Collector using the host and port below." - }, - "syslog": { - "sections": { - "sendLogs": { - "title": "1 · Send logs to UTMStack", - "body": "Configure your device to send syslog messages over UDP (514) or TCP (514) to the UTMStack agent." - }, - "enableCollector": { - "title": "2 · Enable the syslog collector", - "body": "Enable the log collector and the syslog integration in the configuration file where your UTMStack agent is installed." - }, - "activate": { - "title": "3 · Activate", - "body": "Activate the UTMStack module so events start flowing into Log Explorer." - } - } - }, - "netflow": { - "source": "Network device", - "step1": { - "title": "Enable the NetFlow listener on the Collector", - "body": "On the host where the Collector is installed, run this command to open the NetFlow collector on port 2055:", - "note": "NetFlow uses UDP only — TCP and TLS are not supported for this protocol." - }, - "step2": { - "title": "Configure your device to export NetFlow", - "body": "Point NetFlow export on your router or firewall at the Collector host on port {{port}} UDP. The example below is for Cisco IOS — consult your vendor's documentation for other platforms:", - "note": "Replace with the interface name where traffic should be monitored (e.g. GigabitEthernet0/0). Apply ingress/egress on each relevant interface." - } - }, - "cisco": { - "source": "Cisco ASA", - "step1": { - "title": "Enable the Cisco ASA listener on the Collector", - "body": "On the host where the Collector is installed, run this command to open the Cisco ASA log listener:", - "note": "To use TCP instead of UDP, replace udp with tcp in the command above." - }, - "step2": { - "title": "Configure Cisco ASA to forward logs", - "body": "On your Cisco ASA, enable syslog and point it at the Collector host on port {{port}}. Run these commands in privileged EXEC mode (replace with your inside or management interface name):" - } - }, - "ciscoSwitch": { - "source": "Cisco Switch", - "step1": { - "title": "Enable the Cisco Switch listener on the Collector", - "body": "On the host where the Collector is installed, run this command to open the Cisco Switch log listener:", - "note": "To use TCP instead of UDP, replace udp with tcp in the command above." - }, - "step2": { - "title": "Configure the switch to forward logs", - "body": "In privileged EXEC mode on your Cisco switch, enable syslog and point it at the Collector host on port {{port}}:" - } - }, - "ciscoMeraki": { - "source": "Cisco Meraki", - "step1": { - "title": "Enable the Cisco Meraki listener on the Collector", - "body": "On the host where the Collector is installed, run this command to open the Cisco Meraki log listener:", - "note": "To use TCP instead of UDP, replace udp with tcp in the command above." - }, - "step2": { - "title": "Configure Meraki to forward logs", - "body": "In the Meraki Dashboard, go to Network-wide → Configure → General, scroll to the Reporting section and add a syslog server with the Collector IP and port {{port}}. Select all roles you want to forward." - } - }, - "ciscoFirepower": { - "source": "Cisco Firepower", - "step1": { - "title": "Enable the Cisco Firepower listener on the Collector", - "body": "On the host where the Collector is installed, run this command to open the Cisco Firepower log listener:", - "note": "To use TCP instead of UDP, replace udp with tcp in the command above." - }, - "step2": { - "title": "Configure Firepower to forward logs", - "body": "In Firepower Management Center (FMC), go to Devices → Platform Settings, edit or create a policy and navigate to Syslog → Syslog Servers. Add the Collector IP with port {{port}} (UDP), then assign the policy to your devices and deploy." - } - }, - "vmware": { - "source": "VMware ESXi", - "step1": { - "title": "Enable the VMware listener on the Collector", - "body": "On the host where the Collector is installed, run this command to open the VMware ESXi syslog listener. ESXi streams over TCP:", - "note": "For an encrypted channel use tls instead of tcp (load certificates on the Collector first)." - }, - "step2": { - "title": "Point ESXi syslog at the Collector", - "body": "Open an SSH/ESXi Shell session on the host (or use the vSphere Client: Host → Configure → Advanced System Settings → Syslog.global.logHost). Set the remote loghost to {{host}}:{{port}} and reload the configuration:", - "note": "On vSphere you can instead set Syslog.global.logHost to the same tcp://host:port value rather than running esxcli." - }, - "step3": { - "title": "Open the ESXi firewall for syslog", - "body": "Allow outbound syslog through the ESXi firewall so the host can reach the Collector:" - } - }, - "as400": { - "intro": { - "title": "How it works", - "body": "The AS/400 Collector is a Linux service that connects directly to your AS/400 (IBM i) systems and pulls security journal entries, then streams them securely to UTMStack for correlation and alerting.", - "note": "Nothing is installed on the AS/400 itself — the Collector runs on a Linux host that has network access to your AS/400 systems.", - "diagram": { - "source": "your journals", - "edge1": "journals", - "collector": "AS/400 Collector", - "collectorSub": "pulls from AS/400", - "edge2": "secure", - "utmstackSub": "alerts & correlation" - } - }, - "install": { - "title": "Install the AS/400 Collector", - "body": "Run this command on a Linux host that can reach both UTMStack and your AS/400 systems over the network.", - "reuse": "Already have the AS/400 Collector installed? Skip this step — just add your servers to the configuration file in the next step." - }, - "configure": { - "title": "Add your AS/400 servers", - "body": "Edit as400-config.yaml in the collector's installation directory and add each AS/400 system you want to monitor:", - "note": "You can list multiple servers. The collector watches this file and reloads automatically on save — no restart needed." - }, - "journal": { - "title": "Enable audit journaling on AS/400", - "body": "On each AS/400 system, make sure the QAUDJRN security audit journal is active. Refer to IBM's documentation for the exact steps — the procedure varies between IBM i versions." - }, - "uninstall": { - "title": "Optional — Uninstall the Collector", - "body": "Run this command on the host where the AS/400 Collector is installed to stop the service and remove all files." - } - }, - "bitdefender": { - "intro": { - "title": "How it works", - "body": "UTMStack connects to Bitdefender GravityZone using your API key to configure the Event Push Service. GravityZone then sends security events directly to UTMStack for correlation and alerting.", - "diagram": { - "source": "endpoint events", - "edge": "Event Push Service", - "utmstackSub": "alerts & correlation" - }, - "note": "No agent is installed on GravityZone — UTMStack registers itself as the push destination using read-only API credentials." - }, - "whitelist": { - "title": "Whitelist Bitdefender IPs", - "body": "The following Bitdefender GravityZone IP addresses must be allowed through your firewall on port 8000 so that the Event Push Service can reach UTMStack:", - "note": "Add these IPs to your firewall or security group before completing the setup." - }, - "apiSection": "Get API credentials", - "api": { - "myAccount": { - "title": "Open My Account", - "body": "In the Bitdefender GravityZone console, click on My Account." - }, - "accessUrl": { - "title": "Note the Access URL", - "body": "Scroll down to the Control Center API section and save the Access URL — you will enter it in the credentials form below. Then open the API key section and click Add at the top of the table." - }, - "createKey": { - "title": "Create an API key", - "body": "Write a description for the API key, select the Event Push Service API option, and click Save. Copy the generated key." - } - }, - "companySection": "Get Company IDs", - "company": { - "myCompany": { - "title": "Open My Company", - "body": "In the GravityZone console, click on My Company." - }, - "licensing": { - "title": "Note the Company IDs", - "body": "Open the Licensing section and save the Company IDs you want to monitor — enter them comma-separated in the credentials form below." - } - }, - "credentials": { - "title": "Enter credentials", - "body": "Fill in the Access URL, API key, your UTMStack public IP (where GravityZone will push events), and the Company IDs to monitor. UTMStack verifies the credentials before saving." - }, - "fields": { - "accessUrl": { - "label": "GravityZone Access URL" - }, - "connectionKey": { - "label": "API key" - }, - "utmPublicIP": { - "label": "UTMStack public IP" - }, - "companyIds": { - "label": "Company IDs (comma-separated)" - } - } - }, - "eset": { - "source": "ESET Protect", - "step1": { - "title": "Enable the ESET listener on the Collector", - "body": "On the host where the Collector is installed, run this command to open the ESET syslog listener:", - "note": "To use TCP instead of UDP, replace udp with tcp in the command above." - }, - "console": { - "moreMenu": { - "title": "Open the More menu", - "body": "In the ESET Protect console sidebar, click the More menu." - }, - "serverConfig": { - "title": "Open Server settings", - "body": "Under More, open the Server settings (Server configuration) section." - }, - "advanced": { - "title": "Expand Advanced settings", - "body": "Click Advanced settings to expand the full list of configuration options." - }, - "syslog": { - "title": "Configure the Syslog server", - "body": "Scroll to Syslog server, enable Export logs to Syslog, and set the destination to the Collector host on port {{port}} (UDP). ESET sends LEEF/syslog, which the Collector ingests as the antivirus-esmc-eset data type." - } - } - }, - "kaspersky": { - "source": "Kaspersky Security", - "step1": { - "title": "Enable the Kaspersky listener on the Collector", - "body": "On the host where the Collector is installed, run this command to open the Kaspersky syslog listener:", - "note": "To use TCP instead of UDP, replace udp with tcp in the command above." - }, - "console": { - "consoleSettings": { - "title": "Open Console settings → Integration", - "body": "In the Kaspersky Security Center sidebar, open Console settings and click the Integration submenu." - }, - "siem": { - "title": "Open the SIEM integration settings", - "body": "Under Integration, select SIEM and click the Settings link to open the export configuration." - }, - "configure": { - "title": "Configure the SIEM export", - "body": "Enable export and set Kaspersky to send events in Splunk (CEF) format to the Collector host on port {{port}} (UDP). The Collector ingests them as the antivirus-kaspersky data type." - } - } - }, - "sophos": { - "intro": { - "title": "Sophos Central — API Plugin", - "body": "Sophos Central provides secure APIs to retrieve event and alert data. UTMStack connects to those APIs to centralize monitoring and enhance your security visibility — no agent or collector required.", - "diagram": { - "source": "Sophos Central API", - "edge": "HTTPS API", - "utmstackSub": "Ingests & correlates" - }, - "note": "UTMStack polls the Sophos Central API on a schedule. Ensure the API credentials you create below have read access to events and alerts." - }, - "apiSection": "Generate API Credentials in Sophos Central", - "steps": { - "apiCredentials": { - "title": "Open API Credentials Management", - "body": "In Sophos Central Admin, navigate to Global Settings → API Credentials Management." - }, - "addCredential": { - "title": "Create a new credential", - "body": "Click Add Credential. Provide a Name and Description, select the appropriate Role, then click Add." - }, - "copyIds": { - "title": "Copy Client ID and Client Secret", - "body": "Copy the Client ID and Client Secret and store them securely.", - "secretNote": "The Client Secret is shown only once. Save it somewhere safe before closing this dialog." - } - }, - "credentialsSection": "Connect to UTMStack", - "credentials": { - "title": "Add Sophos Central credentials", - "body": "Enter the credentials you just created. You can add more than one Sophos account by clicking Add config group." - }, - "fields": { - "clientId": { - "label": "Client ID" - }, - "apiKey": { - "label": "Client Secret / API Key" - } - } - }, - "webroot": { - "sections": { - "login": { - "title": "1 · Log in to the management console", - "body": "Log in to the Webroot management console. It opens on the Sites tab." - }, - "openSettings": { - "title": "2 · Open Settings", - "body": "Click on the Settings tab." - }, - "apiAccess": { - "title": "3 · Open API Access", - "body": "From the Subscriptions tab, click on the API Access tab." - }, - "createCredential": { - "title": "4 · Create a client credential", - "body": "Click New and fill in the Name and Description. Read the SecureAnywhere Business Solution and Unity API agreement, then click Create." - }, - "noteClientSecret": { - "title": "5 · Copy the client ID and secret", - "body": "Save the Client ID from the list and the Client Secret that's shown only once. Click \"I have made note of the client secret\" to confirm." - }, - "fillForm": { - "title": "6 · Fill the form", - "body": "Provide the client ID and client secret to UTMStack. You can add more than one Webroot config group if needed." - }, - "activate": { - "title": "7 · Activate", - "body": "Activate the UTMStack module so Webroot events start flowing." - } - } - }, - "sentinelOne": { - "source": "SentinelOne", - "step1": { - "title": "Enable the SentinelOne listener on the Collector", - "body": "On the host where the Collector is installed, run this command to open the SentinelOne syslog listener. SentinelOne streams CEF over TCP:", - "note": "For an encrypted channel use tls instead of tcp (load certificates on the Collector first)." - }, - "console": { - "settings": { - "title": "Open the SentinelOne Settings", - "body": "In the SentinelOne management console sidebar, click the Settings menu." - }, - "syslog": { - "title": "Configure the Syslog integration", - "body": "Go to Integrations → Syslog and enable it. Set the host to {{host}} and port to {{port}}, keep the format as CEF, click Test to verify the connection, then Save." - } - } - }, - "office365": { - "intro": { - "title": "How it works", - "body": "UTMStack connects to Microsoft 365 using a registered Azure AD app and polls the Office 365 Management Activity API for audit and security events. No agent is installed in your tenant.", - "diagram": { - "source": "audit & security events", - "edge": "Management API", - "utmstackSub": "correlation & alerts" - }, - "note": "UTMStack requires read-only API access — no write permissions are requested." - }, - "appSection": "Azure App Registration", - "steps": { - "azurePortal": { - "title": "Open Microsoft Entra ID", - "body": "Open the Azure Portal (portal.azure.com) and click on Microsoft Entra ID." - }, - "appRegistrations": { - "title": "Go to App registrations", - "body": "In the left menu, click App registrations." - }, - "registerApp": { - "title": "Register a new app", - "body": "Click New registration. Name it UTMStack O365 Agent, select Accounts in this organizational directory only (Single-tenant), and click Register." - }, - "clientSecret": { - "title": "Create a client secret", - "body": "Go to Certificates & Secrets → New client secret. Add a description, set expiry to 730 days (24 months), and click Add.", - "copyNote": "Copy the secret Value immediately — it is only shown once and cannot be retrieved later." - }, - "apiPermissions": { - "title": "Add Office 365 Management API permissions", - "body": "Go to API Permissions → Add a permission and search for Office 365 Management APIs." - }, - "activityFeed": { - "title": "Grant ActivityFeed permissions", - "body": "Select Application Permissions and add ActivityFeed.Read and ActivityFeed.ReadDlp. Click Grant admin consent and confirm." - }, - "graphPermissions": { - "title": "Add Microsoft Graph permissions", - "body": "Back in Add a permission, click Microsoft Graph." - }, - "delegatedPermissions": { - "title": "Add delegated SecurityAlert permissions", - "body": "Select Delegated Permissions and add SecurityAlert.Read.All and SecurityAlert.ReadWrite.All. Click Grant admin consent and confirm." - }, - "appPermissions": { - "title": "Add application SecurityAlert permissions", - "body": "Select Application Permissions and add SecurityAlert.Read.All and SecurityAlert.ReadWrite.All. Click Grant admin consent and confirm." - }, - "noteIds": { - "title": "Copy the app IDs", - "body": "Go to the app Overview and copy the Application (client) ID and Directory (tenant) ID. You also need the secret value copied in step 4." - } - }, - "credentialsSection": "Credentials", - "credentials": { - "title": "Connect your Microsoft 365 tenant", - "body": "Enter the details from the steps above. UTMStack verifies the credentials before saving. You can add multiple config groups." - }, - "fields": { - "tenantId": { - "label": "Tenant ID (Directory ID)" - }, - "clientId": { - "label": "Client ID (Application ID)" - }, - "clientSecret": { - "label": "Client Secret" - }, - "cloudEnv": { - "label": "Cloud Environment (optional)", - "hint": "Commercial (default), GCC, GCCHigh, or DoD" - } - } - }, - "github": { - "source": "GitHub", - "step1": { - "title": "Enable the GitHub webhook listener on the Collector", - "body": "On the host where the Collector is installed, run this command to open the HTTPS webhook listener for GitHub:", - "tokenNote": "The terminal will print a secret token — copy it immediately. It will not be shown again." - }, - "certWarning": { - "title": "GitHub requires a CA-signed TLS certificate", - "body": "GitHub only delivers webhooks to HTTPS endpoints with a certificate issued by a public CA (self-signed certificates are rejected). Make sure the Collector host has a valid domain certificate before registering the webhook." - }, - "step2": { - "title": "Register the webhook in GitHub", - "body": "In your repository or organization, go to Settings → Webhooks → Add webhook and fill in the form:", - "payloadUrl": "Payload URL", - "contentType": "Content type", - "secret": "Secret", - "secretHint": "Paste the token shown when the integration was enabled above.", - "events": "Which events", - "eventsHint": "Send me everything — or select specific event types." - } - }, - "salesforce": { - "sections": { - "openSetup": { - "title": "1 · Open Setup", - "body": "Go to Setup and select \"Setup for the current app\" at the top right of the screen." - }, - "appManager": { - "title": "2 · Open App Manager", - "body": "Type \"App Manager\" in the quick search box and select App Manager." - }, - "newConnectedApp": { - "title": "3 · Create a new Connected App", - "body": "On the Lightning Experience App Manager screen, click \"New Connected App\" and fill in the fields." - }, - "oauthSettings": { - "title": "4 · Enable OAuth Settings", - "body": "In the \"API (Enable OAuth Settings)\" section, check \"Enable OAuth Settings\" and use https://login.salesforce.com/services/oauth2/success as the Callback URL." - }, - "oauthScopes": { - "title": "5 · Add OAuth scopes", - "body": "Select \"Access Connect REST API resources (chatter_api)\" under Selected OAuth Scopes." - }, - "save": { - "title": "6 · Save", - "body": "Save your changes and select Continue on the next screen." - }, - "manageConsumer": { - "title": "7 · Open Manage Consumer Details", - "body": "Inside your Connected App, go to \"API (Enable OAuth Settings)\" and click \"Manage Consumer Details\" next to Consumer Key and Secret." - }, - "copyCredentials": { - "title": "8 · Copy the consumer key and secret", - "body": "Verify your identity. The Consumer Key and Consumer Secret appear under \"Consumer Details\". Copy both with the Copy button." - }, - "fillForm": { - "title": "9 · Fill the form", - "body": "Provide the Consumer Key, Consumer Secret, Salesforce username and password to UTMStack." - }, - "activate": { - "title": "10 · Activate", - "body": "Activate the UTMStack module so Salesforce events start flowing." - } - } - }, - "iis": { - "sections": { - "enableModule": { - "title": "1 · Enable the IIS Filebeat module", - "body": "On the UTMStack agent host, run:\ncd \"C:\\Program Files\\UTMStack\\UTMStack Agent\\beats\\filebeat\\\" && filebeat modules enable iis" - }, - "configureModule": { - "title": "2 · Configure the IIS module", - "body": "Edit C:\\Program Files\\UTMStack\\UTMStack Agent\\beats\\filebeat\\modules.d\\iis.yml as shown below to point at the IIS log directories you want to ship." - }, - "activate": { - "title": "3 · Activate", - "body": "Activate the UTMStack module so IIS events start flowing." - } - } - }, - "filebeat": { - "sections": { - "installRsyslog": { - "title": "1 · Install rsyslog", - "body": "Ensure rsyslog is installed on the host. Use your distribution's package manager (apt, dnf, yum)." - }, - "configureRsyslog": { - "title": "2 · Configure rsyslog to forward to UTMStack", - "body": "Edit /etc/rsyslog.conf (or a file under /etc/rsyslog.d/) and add a forwarding rule that targets the UTMStack agent over UDP or TCP on port 514." - }, - "restartRsyslog": { - "title": "3 · Restart rsyslog", - "body": "Restart the rsyslog service: sudo systemctl restart rsyslog" - }, - "enableCollector": { - "title": "4 · Enable the Linux logs collector", - "body": "Enable the log collector and the Linux Logs integration in the configuration file where your UTMStack agent is installed." - } - } - }, - "json": { - "sections": { - "overview": { - "title": "1 · Use the HTTP/JSON ingestion endpoint", - "body": "UTMStack accepts arbitrary JSON events over HTTPS. Send a POST request with a list of events; UTMStack parses them and routes through your configured parser." - }, - "auth": { - "title": "2 · Authenticate with a federation token", - "body": "Get a federation token from Settings → Connection Key and send it as a Bearer token in the Authorization header." - } - }, - "endpoint": { - "title": "JSON ingestion endpoint", - "hint": "Use this request shape from your application or a cron job. The token is the federation key from Settings → Connection Key." - } - }, - "ldap": { - "sections": { - "openServerManager": { - "title": "1 · Open Server Manager", - "body": "On the AD domain controller, open Server Manager." - }, - "addRoles": { - "title": "2 · Add Roles and Features", - "body": "Choose \"Add roles and features\" from the Manage menu." - }, - "selectCertServices": { - "title": "3 · Select Active Directory Certificate Services", - "body": "On the Server Roles step, select Active Directory Certificate Services." - }, - "installServices": { - "title": "4 · Install the Certificate Authority role service", - "body": "On the Role Services step, select Certificate Authority and finish the wizard." - }, - "configureAdCs": { - "title": "5 · Configure AD CS", - "body": "After install, click the notification to configure AD CS and choose Certificate Authority as the role service to configure." - }, - "pickCaType": { - "title": "6 · Pick the CA type", - "body": "Choose Enterprise CA → Root CA → Create a new private key." - }, - "setValidity": { - "title": "7 · Set the certificate validity period", - "body": "Set a validity period that fits your organization (5 years is typical)." - }, - "confirm": { - "title": "8 · Confirm and install", - "body": "Review the settings and click Configure to finish." - }, - "restart": { - "title": "9 · Restart the domain controller", - "body": "Restart the domain controller so LDAPS becomes available on TCP 636." - }, - "activate": { - "title": "10 · Activate", - "body": "Activate the UTMStack module so AD audit events start flowing." - } - } - }, - "oracle": { - "source": "Oracle DB server", - "step1": { - "title": "Enable the Oracle integration on the Collector", - "body": "On the server where the Collector is installed, run the following command to start listening for Oracle logs:", - "note": "The Collector will begin receiving syslog events from Oracle on port 7021." - }, - "step2": { - "title": "Configure rsyslog on the Oracle server", - "body": "Create the rsyslog configuration file:", - "editBody": "Open the file with your preferred editor and add the following configuration. Replace BASEDIR with your Oracle installation path (e.g., /u01/app/oracle) and with the Collector's IP address or hostname:", - "note": "Use @@:7021 instead of @ if you prefer TCP delivery." - }, - "step3": { - "title": "Restart rsyslog", - "body": "Apply the new configuration by restarting the rsyslog service:" - }, - "step4": { - "title": "Validate the configuration", - "body": "Send test log messages to verify that UTMStack is receiving events from all three Oracle log sources:", - "note": "Open Log Explorer and search for the test message text above to confirm they arrived." - } - }, - "vulnerabilities": { - "sections": { - "overview": { - "title": "1 · About the vulnerabilities scanner", - "body": "The UTMStack vulnerabilities module scans assets discovered through the Asset Management module and matches their fingerprint against the CVE database." - }, - "scope": { - "title": "2 · Define scan scope", - "body": "Use the Asset Management module to register the hosts you want scanned. The vulnerabilities scanner will run periodically against them." - }, - "activate": { - "title": "3 · Activate", - "body": "Activate the UTMStack module to start scanning." - } - } - }, - "assetScanner": { - "sections": { - "overview": { - "title": "1 · About Asset Management", - "body": "The Asset Management module discovers and inventories hosts, software, and services across your network." - }, - "agentRequirement": { - "title": "2 · Agent requirement", - "body": "Asset discovery uses UTMStack agents running on Linux, Windows, or macOS hosts. Install the agent on the systems you want inventoried." - }, - "activate": { - "title": "3 · Activate", - "body": "Activate the UTMStack module to start asset discovery." - } - } - }, - "fileIntegrity": { - "sections": { - "enableAuditPolicy": { - "title": "1 · Enable Audit Object Access", - "body": "On the Windows host, open Group Policy → Computer Configuration → Windows Settings → Security Settings → Advanced Audit Policy Configuration → Object Access and enable \"Audit File System\"." - }, - "configureFolderAuditing": { - "title": "2 · Configure folder auditing", - "body": "On each folder you want monitored, open Properties → Security → Advanced → Auditing and add an auditing entry for the principals and access types you care about." - }, - "verifyEvents": { - "title": "3 · Verify events appear in Security log", - "body": "Open Event Viewer and confirm 4663/4670 events are being generated when the audited objects are accessed." - }, - "activate": { - "title": "4 · Activate", - "body": "Activate the UTMStack module so file integrity events start flowing." - } - } - }, - "socAi": { - "sections": { - "overview": { - "title": "1 · About SOC AI", - "body": "SOC AI augments UTMStack with an LLM-backed analyst that summarizes alerts and suggests next steps. It runs against the provider you configure." - }, - "chooseProvider": { - "title": "2 · Choose a provider", - "body": "Pick a provider — OpenAI, Anthropic, Azure OpenAI, Google Gemini, Ollama, Mistral, DeepSeek, Groq, or a custom OpenAI-compatible endpoint." - }, - "configureCredentials": { - "title": "3 · Configure credentials", - "body": "Provide the API key and (where applicable) the model name and endpoint URL." - }, - "activate": { - "title": "4 · Activate", - "body": "Activate the UTMStack module so SOC AI starts working on alerts." - } - } - }, - "utmstack": { - "intro": { - "title": "How it works", - "body": "This integration self-monitors your UTMStack deployment. A lightweight collector installed on the UTMStack host tails the platform's own Docker container logs and ships them back into UTMStack for correlation and alerting.", - "diagram": { - "source": "Docker logs", - "sourceSub": "UTMStack containers", - "edge1": "tail", - "collector": "Collector", - "collectorSub": "on the host", - "edge2": "ingest", - "utmstackSub": "Correlates & alerts" - } - }, - "requirements": { - "title": "Runs on the UTMStack host only", - "body": "This integration can only be installed on a UTMStack instance running Ubuntu or a Red Hat-family distribution. Install the collector directly on the UTMStack server." - }, - "install": { - "title": "Install the collector", - "body": "On the UTMStack host, pick your operating system and run the command below to download and install the self-monitoring collector:", - "sensitiveWarning": "This command contains a sensitive connection token. Treat it like a password and don't share it." - }, - "after": { - "title": "What you'll see after installing", - "item1": "The collector registers itself and appears under Data sources.", - "item2": "UTMStack container logs start flowing within a minute.", - "item3": "Events become searchable in Log Explorer under the utmstack data type." - }, - "uninstall": { - "title": "Uninstall the collector", - "body": "To remove the self-monitoring collector from the UTMStack host, run:" - } - }, - "windowsFaa": { - "sections": { - "enableAuditPolicy": { - "title": "1 · Enable Audit Object Access", - "body": "On the Windows host, open Group Policy → Computer Configuration → Windows Settings → Security Settings → Advanced Audit Policy Configuration → Object Access and enable \"Audit File System\"." - }, - "configureFolderAuditing": { - "title": "2 · Configure folder auditing", - "body": "On each folder you want monitored, open Properties → Security → Advanced → Auditing and add an auditing entry for the principals and access types you care about." - }, - "activate": { - "title": "3 · Activate", - "body": "Activate the UTMStack module so file activity events start flowing." - } - } - }, - "awsBeanstalk": { - "sections": { - "openConsole": { - "title": "1 · Open the Elastic Beanstalk console", - "body": "In the AWS Console, open Elastic Beanstalk." - }, - "environment": { - "title": "2 · Open the environment management page", - "body": "Navigate to the management page for the environment you want to monitor." - }, - "configuration": { - "title": "3 · Open Configuration", - "body": "Choose Configuration." - }, - "software": { - "title": "4 · Modify the Software configuration", - "body": "In the Software configuration category, choose Modify." - }, - "s3LogStorage": { - "title": "5 · Enable S3 log storage", - "body": "Under S3 log storage, choose Rotate logs to upload rotated logs to Amazon S3." - }, - "cloudwatchStreaming": { - "title": "6 · Enable CloudWatch Logs streaming", - "body": "Under Instance log streaming to CloudWatch Logs, enable streaming, set the retention period, and pick whether to upload existing logs." - }, - "activate": { - "title": "7 · Activate", - "body": "Activate the UTMStack module so Beanstalk events start flowing." - } - } - }, - "awsFargate": { - "sections": { - "taskDefinition": { - "title": "1 · Update your task definition", - "body": "In the task definition for the Fargate task, set the logDriver to \"awslogs\" and define the log group name." - }, - "cloudwatchLogs": { - "title": "2 · Confirm CloudWatch Logs is receiving logs", - "body": "Open the CloudWatch Logs console and confirm the log group is being populated when tasks run." - }, - "iamPrerequisite": { - "title": "3 · IAM user prerequisite", - "body": "This integration shares credentials with the AWS IAM User module — make sure it's configured with CloudWatchLogsReadOnlyAccess." - }, - "activate": { - "title": "4 · Activate", - "body": "Activate the UTMStack module so Fargate events start flowing." - } - } - }, - "awsIamUser": { - "sections": { - "iamConsole": { - "title": "1 · Open the IAM console", - "body": "In the AWS console, go to IAM → Users → Add users." - }, - "createUser": { - "title": "2 · Create the user", - "body": "Pick a username (e.g. utmstack-ingest). Choose programmatic access." - }, - "programmaticAccess": { - "title": "3 · Set credential type", - "body": "Select \"Access key — Programmatic access\"." - }, - "attachPolicy": { - "title": "4 · Attach the CloudWatch read policy", - "body": "Attach the AWS-managed policy CloudWatchLogsReadOnlyAccess." - }, - "review": { - "title": "5 · Review the user", - "body": "Review the user details and click Create user." - }, - "copyKeys": { - "title": "6 · Copy the access key ID and secret", - "body": "Copy the Access key ID and the Secret access key — the secret is shown only once." - }, - "createLogGroup": { - "title": "7 · Create a CloudWatch log group", - "body": "In CloudWatch → Log groups, create a log group named \"utmstack\" — other AWS integrations will deliver to it." - }, - "fillForm": { - "title": "8 · Fill the form", - "body": "Provide the access key, secret, default region, and the log group name (e.g. \"utmstack\") to UTMStack." - }, - "activate": { - "title": "9 · Activate", - "body": "Activate the UTMStack module so AWS events start flowing." - } - } - }, - "awsLambda": { - "sections": { - "iamPrerequisite": { - "title": "1 · IAM user prerequisite", - "body": "Lambda relies on the AWS IAM User module — make sure that integration is configured first with CloudWatchLogsReadOnlyAccess." - }, - "cloudwatchStream": { - "title": "2 · Lambda already streams to CloudWatch Logs", - "body": "AWS Lambda automatically publishes execution logs to CloudWatch Logs under /aws/lambda/. UTMStack ingests from the log group you configured in the IAM user setup." - }, - "activate": { - "title": "3 · Activate", - "body": "Activate the UTMStack module so Lambda events start flowing." - } - } - }, - "awsSqlServer": { - "sections": { - "openRds": { - "title": "1 · Open the Amazon RDS console", - "body": "Open https://console.aws.amazon.com/rds/." - }, - "pickDb": { - "title": "2 · Pick the DB instance", - "body": "In the navigation pane, choose Databases and select the DB instance you want to monitor." - }, - "modify": { - "title": "3 · Modify the instance", - "body": "Choose Modify." - }, - "logExports": { - "title": "4 · Enable Log Exports", - "body": "In the Log exports section, choose Error log and Agent log to publish to CloudWatch Logs." - }, - "apply": { - "title": "5 · Apply changes", - "body": "Choose Continue, then Modify DB Instance on the summary page." - }, - "activate": { - "title": "6 · Activate", - "body": "Activate the UTMStack module so SQL Server events start flowing." - } - } - }, - "awsPostgresql": { - "sections": { - "openRds": { - "title": "1 · Open the Amazon RDS console", - "body": "Open https://console.aws.amazon.com/rds/." - }, - "pickDb": { - "title": "2 · Pick the DB instance", - "body": "In the navigation pane, choose Databases and select the DB instance you want to modify." - }, - "logExports": { - "title": "3 · Enable Log Exports", - "body": "In the Log exports section, choose the PostgreSQL log to publish to CloudWatch Logs." - }, - "apply": { - "title": "4 · Apply changes", - "body": "Choose Continue, then Modify DB Instance on the summary page." - }, - "activate": { - "title": "5 · Activate", - "body": "Activate the UTMStack module so PostgreSQL events start flowing." - } - } - }, - "awsTrafficMirror": { - "sections": { - "createTarget": { - "title": "1 · Create a traffic mirror target", - "body": "In the VPC console, create a Traffic Mirror Target that points at the network interface of the UTMStack agent VM." - }, - "createFilter": { - "title": "2 · Create a traffic mirror filter", - "body": "Create a Traffic Mirror Filter and add inbound/outbound rules for the protocols you want to mirror (e.g. all TCP, all UDP)." - }, - "createSession": { - "title": "3 · Create a traffic mirror session", - "body": "Create a Traffic Mirror Session that pairs each source network interface with the target and filter you created." - }, - "iamPrerequisite": { - "title": "4 · IAM user prerequisite", - "body": "Make sure the AWS IAM User module is also configured so UTMStack can read VPC flow logs if needed." - }, - "activate": { - "title": "5 · Activate", - "body": "Activate the UTMStack module so mirrored traffic starts being parsed." - } - } - }, - "forwarder": { - "intro": { - "title": "How it works", - "body": "Logs flow from {{source}} to the UTMStack Collector, which streams them securely into UTMStack for correlation and alerting. Nothing is installed on {{source}} — only the Collector needs to run on a host in your network." - }, - "diagram": { - "sourceSub": "your logs", - "forwarder": "Collector", - "forwarderSub": "listens on {{port}}", - "utmstack": "UTMStack", - "utmstackSub": "alerts & correlation", - "flow1": "logs", - "flow2": "secure" - }, - "noInstall": "Nothing is installed on {{source}} — you only redirect its logs to the Collector.", - "install": { - "title": "Install the UTMStack Collector", - "body": "The Collector is a Linux service that receives logs from your devices and sends them to UTMStack. A single Collector handles multiple integrations at the same time.", - "reuse": "Already have a Collector running? Skip this step — point {{source}} at the existing one using the host and port shown below." - }, - "tls": { - "title": "Optional — Enable TLS encryption", - "intro": "By default the listener accepts plain TCP/UDP. To encrypt syslog traffic in transit, load your certificate files first, then re-enable the listener with the tls protocol.", - "step1": "1 · Load your certificate and key (once per Collector)", - "step1Note": "An optional CA certificate can be added as a third argument. Omit it to use the leaf certificate as CA.", - "step2": "2 · Re-enable the listener using TLS" - }, - "httpsCerts": { - "title": "Load the TLS certificate on the Collector", - "body": "This integration uses an HTTPS listener on port {{port}}, so the Collector needs a certificate and key loaded before enabling it:" - }, - "uninstall": { - "title": "Optional — Uninstall the Collector", - "body": "Run this command on the host where the Collector is installed to stop the service and remove all its files." - }, - "manualCommand": { - "title": "Optional — Enable via the command line instead", - "intro": "Prefer the terminal? SSH into the Collector host and run the command below — it matches whatever protocol and port you have selected above.", - "certStep": "1 · Load your certificate and key (once per Collector)", - "enableStep": "2 · Enable the integration" - }, - "instanceHeader": { - "title": "Authorization header", - "body": "Include this Authorization header on every request you send to the instance. The API key's secret is revealed only once when it is generated — copy it then and paste it in place of the placeholder below.", - "tabSimple": "Simple", - "tabBatch": "Batch" - } - }, - "aix": { - "source": "AIX server", - "step1": { - "title": "Enable the AIX listener on the Collector", - "body": "On the host where the Collector is installed, run this command to open the AIX log listener:", - "note": "To use TCP instead of UDP, replace udp with tcp in the command above." - }, - "step2": { - "title": "Configure AIX to forward logs", - "body": "On your AIX system, configure the syslog service to redirect its logs to the Collector host on port {{port}}. Refer to IBM’s documentation for the exact syntax — it varies between AIX versions." - } - }, - "deceptivebytes": { - "source": "Deceptive Bytes", - "step1": { - "title": "Enable the Deceptive Bytes listener on the Collector", - "body": "On the host where the Collector is installed, run this command to open the Deceptive Bytes syslog listener:", - "note": "To use TCP instead of UDP, replace udp with tcp in the command above." - }, - "step2": { - "title": "Configure Deceptive Bytes to forward logs", - "body": "In the Deceptive Bytes management console, configure syslog forwarding to send events to the Collector host on port {{port}} (UDP). Deceptive Bytes emits CEF-formatted syslog, which the Collector ingests as the deceptive-bytes data type." - } - }, - "mikrotik": { - "source": "MikroTik router", - "step1": { - "title": "Enable the MikroTik listener on the Collector", - "body": "On the host where the Collector is installed, run this command to open the MikroTik syslog listener:", - "note": "To use TCP instead of UDP, replace udp with tcp in the command above." - }, - "step2": { - "title": "Configure MikroTik to forward logs", - "body": "On the MikroTik router, create a remote logging action pointing at the Collector host on port {{port}} and attach it to the relevant log topics. Run the following from the RouterOS CLI (Terminal in Winbox):", - "note": "You can also configure this via Winbox: System → Logging → Actions tab (add a Remote action) → then the Rules tab (add rules pointing to the new action)." - } - }, - "fortigate": { - "source": "FortiGate firewall", - "step1": { - "title": "Enable the FortiGate listener on the Collector", - "body": "On the host where the Collector is installed, run this command to open the FortiGate syslog listener:", - "note": "To use TCP instead of UDP, replace udp with tcp in the command above." - }, - "step2": { - "title": "Configure FortiGate to forward logs", - "body": "On the FortiGate, point syslog at the Collector host on port {{port}}. Run the following from the FortiOS CLI (or use Log & Report → Log Settings → Syslog in the GUI):", - "note": "Replace the server address if the Collector runs on a different host. For multiple syslog collectors use syslogd2/syslogd3/syslogd4." - } - }, - "fortiweb": { - "source": "FortiWeb WAF", - "step1": { - "title": "Enable the FortiWeb listener on the Collector", - "body": "On the host where the Collector is installed, run this command to open the FortiWeb syslog listener:", - "note": "To use TCP instead of UDP, replace udp with tcp in the command above." - }, - "step2": { - "title": "Configure FortiWeb to forward logs", - "body": "On the FortiWeb, create a syslog policy pointing at the Collector host on port {{port}} and enable syslog logging. Run the following from the FortiWeb CLI (or use Log & Report → Log Policy → Syslog Policy in the GUI):", - "note": "Make sure the relevant log types (Attack, Event, Traffic) are enabled to be sent to syslog under Log & Report settings." - } - }, - "paloalto": { - "source": "Palo Alto firewall", - "step1": { - "title": "Enable the Palo Alto listener on the Collector", - "body": "On the host where the Collector is installed, run this command to open the Palo Alto syslog listener:", - "note": "To use TCP instead of UDP, replace udp with tcp in the command above." - }, - "step2": { - "title": "Create a Syslog Server Profile", - "body": "In PAN-OS, go to Device → Server Profiles → Syslog and add a profile. Set the server address to {{host}}, transport UDP, port {{port}} and format BSD." - }, - "step3": { - "title": "Forward logs and commit", - "body": "Create a Log Forwarding profile (Objects → Log Forwarding) that sends Traffic, Threat and other log types to the syslog profile above, attach it to your Security policy rules (Policies → Security → rule → Actions → Log Forwarding), then Commit." - } - }, - "pfsense": { - "source": "pfSense firewall", - "step1": { - "title": "Enable the pfSense listener on the Collector", - "body": "On the host where the Collector is installed, run this command to open the pfSense syslog listener:", - "note": "To use TCP instead of UDP, replace udp with tcp in the command above." - }, - "step2": { - "title": "Enable Remote Logging in pfSense", - "body": "In the pfSense web UI, go to Status → System Logs → Settings. Under Remote Logging Options, check Enable Remote Logging, set a Remote log server to {{host}}:{{port}}, choose which logs to send (or Everything), and click Save." - } - }, - "sonicwall": { - "source": "SonicWall firewall", - "step1": { - "title": "Enable the SonicWall listener on the Collector", - "body": "On the host where the Collector is installed, run this command to open the SonicWall syslog listener:", - "note": "To use TCP instead of UDP, replace udp with tcp in the command above." - }, - "step2": { - "title": "Add a Syslog Server in SonicOS", - "body": "In SonicOS, go to Device → Log → Syslog (Manage → Log → Syslog on older firmware) and add a Syslog Server with address {{host}} and port {{port}}. Set the Syslog Format to ArcSight (CEF) — UTMStack parses SonicWall in CEF — then Apply." - } - }, - "sophosxg": { - "source": "Sophos Firewall", - "step1": { - "title": "Enable the Sophos Firewall listener on the Collector", - "body": "On the host where the Collector is installed, run this command to open the Sophos Firewall syslog listener:", - "note": "To use TCP instead of UDP, replace udp with tcp in the command above." - }, - "step2": { - "title": "Add a Syslog Server in Sophos Firewall", - "body": "In the Sophos Firewall (SFOS) console, go to System → System services → Log settings and add a Syslog Server with address {{host}} and port {{port}}. Choose the log types you want to forward (firewall, IPS, ATP, web, etc.) and click Apply." - } - }, - "suricata": { - "source": "Suricata IDS", - "step1": { - "title": "Enable the Suricata listener on the Collector", - "body": "On the host where the Collector is installed, run this command to open the Suricata listener:", - "note": "To use TCP instead of UDP, replace udp with tcp in the command above." - }, - "step2": { - "title": "Send Suricata EVE logs to syslog", - "body": "Suricata is ingested as JSON (EVE). On the Suricata host, edit suricata.yaml and configure the eve-log output to write to syslog:", - "note": "Then restart Suricata: sudo systemctl restart suricata" - }, - "step3": { - "title": "Forward syslog to the Collector", - "body": "Point the local5 facility (where Suricata now writes) at the Collector. Add this rule to /etc/rsyslog.d/60-utmstack-suricata.conf on the Suricata host:", - "note": "Use @@ instead of @ for TCP. Then restart rsyslog: sudo systemctl restart rsyslog" - } - }, - "o365_graph": { - "intro": { - "title": "How it works", - "body": "UTMStack connects to Microsoft 365 with a registered Azure AD app and polls Microsoft Graph for security events: alerts, incidents, directory audit, sign-ins, risk detections, hunting queries and Purview audit logs. No agent is installed in your tenant.", - "diagram": { - "source": "security events", - "edge": "Microsoft Graph", - "utmstackSub": "correlation & alerts" - }, - "note": "UTMStack requires read-only Graph API access — no write permissions are requested." - }, - "appSection": "Azure App Registration", - "steps": { - "azurePortal": { - "title": "Open Microsoft Entra ID", - "body": "Open the Azure Portal (portal.azure.com) and click on Microsoft Entra ID." - }, - "appRegistrations": { - "title": "Go to App registrations", - "body": "In the left menu, click App registrations." - }, - "registerApp": { - "title": "Register a new app", - "body": "Click New registration. Name it UTMStack Graph Dev, select Accounts in this organizational directory only (Single-tenant), and click Register." - }, - "clientSecret": { - "title": "Create a client secret", - "body": "Go to Certificates & Secrets → New client secret. Add a description, set expiry to 730 days (24 months), and click Add.", - "copyNote": "Copy the secret Value immediately — it is only shown once and cannot be retrieved later." - }, - "apiPermissions": { - "title": "Add Microsoft Graph permissions", - "body": "Go to API Permissions → Add a permission and select Microsoft Graph, then choose Application permissions." - }, - "graphPermissions": { - "title": "Add the four Graph permissions", - "body": "Add SecurityEvents.Read.All, Directory.Read.All, AuditLog.Read.All and IdentityRiskEvent.Read.All." - }, - "adminConsent": { - "title": "Grant admin consent", - "body": "Back in API Permissions, click Grant admin consent for {tenant} and confirm." - }, - "noteIds": { - "title": "Copy the app IDs", - "body": "Go to the app Overview and copy the Application (client) ID and Directory (tenant) ID. You also need the secret value copied in step 4." - } - }, - "credentialsSection": "Credentials", - "credentials": { - "title": "Connect your Microsoft 365 tenant", - "body": "Enter the details from the steps above. UTMStack verifies the credentials before saving. You can add multiple config groups." - }, - "fields": { - "tenantId": { - "label": "Tenant ID (Directory ID)" - }, - "clientId": { - "label": "Client ID (Application ID)" - }, - "clientSecret": { - "label": "Client Secret" - }, - "cloudEnv": { - "label": "Cloud Environment (optional)", - "hint": "Commercial (default), GCC, GCCHigh, or DoD" - } - } - } - }, - "cloud": { - "howItWorksTitle": "How it works", - "howItWorksBody": "{{name}} runs entirely inside UTMStack — no agent or collector to deploy. Provide read-only API credentials and UTMStack will pull events on a schedule, parse them, and ingest them into Log Explorer.", - "connectionTitle": "Connection", - "noFields": "No connection fields configured.", - "testConnection": "Test connection", - "save": "Save", - "afterTitle": "What you'll see after connecting", - "after1": "UTMStack performs an initial backfill of recent events.", - "after2": "From then on, events are pulled every 1–5 minutes (depends on the API).", - "after3": "The integration appears under Data Sources with current pull status and lag.", - "tenants": { - "title": "Configured config groups", - "empty": "No config groups configured yet. Add your first one below.", - "loading": "Loading config groups…", - "nameLabel": "Config group name", - "namePlaceholder": "e.g. acme-prod", - "add": "Add config group", - "update": "Update config group", - "delete": "Delete", - "edit": "Edit", - "cancel": "Cancel", - "editing": "Editing: {{name}}", - "selectFile": "Select file", - "replaceFile": "Replace file", - "fileLoaded": "File loaded", - "invalidJson": "Could not parse the file as JSON.", - "createError": "Could not create the config group. Please try again.", - "updateError": "Could not update the config group. Please try again.", - "createSuccess": "Config group created successfully.", - "updateSuccess": "Config group updated successfully." - }, - "google": { - "intro": { - "title": "How it works", - "body": "UTMStack reads audit activity directly from Google Cloud via Pub/Sub. A Logs Router sink streams your project logs into a Pub/Sub topic; UTMStack runs an internal puller that reads a Pull subscription on that topic using a service-account key. Nothing is installed in your GCP project.", - "diagram": { - "source": "Cloud Logging", - "edge1": "Logs Router", - "pubsub": "Pub/Sub", - "pubsubSub": "topic + subscription", - "edge2": "pulls", - "utmstackSub": "alerts & correlation" - }, - "note": "No agent runs in GCP — UTMStack pulls messages from the Pub/Sub subscription using the service-account JSON key you provide below." - }, - "sections": { - "createTopic": { - "title": "Create a Pub/Sub topic", - "body": "In the Google Cloud console, open Pub/Sub → Topics and create a new topic. The Logs Router sink will publish your project logs to it.", - "docLabel": "Open the Pub/Sub topics page" - }, - "createSubscription": { - "title": "Create a subscription", - "body": "From the topic menu, create a subscription. UTMStack pulls messages from this subscription." - }, - "configureSubscription": { - "title": "Configure the subscription", - "body": "Leave the Delivery type as Pull and the Expiration as Never expire. The default acknowledgement deadline (10s) and message retention are fine." - }, - "logsRouter": { - "title": "Open Logs Router and create a sink", - "body": "Navigate to Logging → Logs Router and create a new sink. This is what forwards your project logs into the Pub/Sub topic above." - }, - "sinkDestination": { - "title": "Point the sink at the topic", - "body": "Choose Cloud Pub/Sub topic as the sink destination and select the topic you created. Optionally use inclusion/exclusion filters to scope which logs are forwarded, then create the sink." - }, - "serviceAccount": { - "title": "Create a service account", - "body": "Open IAM & Admin → Service Accounts in the project that holds your topic and sink, and create a new service account. Grant it the Pub/Sub Editor role so UTMStack can pull from the subscription.", - "docLabel": "Open the service accounts page" - }, - "serviceAccountKey": { - "title": "Generate a key for the service account", - "body": "Open the service account, go to the Keys tab, and add a new key. Choose JSON as the key type." - }, - "downloadKey": { - "title": "Download the JSON key", - "body": "Save the JSON file Google downloads — its contents go in the Service account JSON key field below. The key is shown only once." - } - }, - "credentials": { - "title": "Pub/Sub configuration", - "body": "Use the values collected above to configure UTMStack. You can monitor more than one project by saving additional configurations.", - "mapping": { - "intro": "Field reference", - "projectId": "Project ID — the GCP project that holds your topic, subscription and sink", - "subscription": "Subscription name — the Pull subscription created in step 2", - "jsonKey": "Service account JSON key — the file downloaded in step 8" - } - }, - "fields": { - "projectId": { - "label": "Project ID" - }, - "subscription": { - "label": "Subscription name" - }, - "jsonKey": { - "label": "Service account JSON key" - } - } - }, - "azure": { - "intro": { - "title": "How it works", - "body": "UTMStack reads audit activity directly from an Azure Event Hub. You configure your Azure subscription to stream events into an Event Hub; UTMStack runs an internal puller that reads that hub and checkpoints its progress in a Storage Account. Nothing is installed in your Azure tenant.", - "diagram": { - "source": "subscription events", - "edge1": "streams to", - "eventHub": "Event Hub", - "eventHubSub": "event stream", - "edge2": "pulls", - "utmstackSub": "alerts & correlation" - }, - "note": "No agent runs in Azure — UTMStack pulls events from the Event Hub using the connection strings you provide below." - }, - "sections": { - "createEventHub": { - "title": "Create an Event Hub", - "body": "In the Azure Portal, create an Event Hubs namespace and an Event Hub inside it. UTMStack will read events from this hub.", - "docLabel": "Quickstart: Create an event hub using the Azure portal" - }, - "sharedAccessPolicy": { - "title": "Add a Shared Access Policy", - "body": "Open the Event Hub → Shared access policies and create a new policy. Make sure you select the Listen permission." - }, - "connectionString": { - "title": "Copy the primary connection string", - "body": "Open the Shared access policy you just created and copy the Connection string–primary key. You will use it to configure your config group below." - }, - "consumerGroup": { - "title": "Create a dedicated consumer group", - "body": "Get the Consumer Group name in: All services → Event Hubs → your namespace → Event Hubs → your instance → Consumer groups. You will use it to configure your config group below.", - "warn": "Create a consumer group specifically for UTMStack. Do not use $Default or any other group already in use — reusing a consumer group across unrelated consumers can cause unexpected behavior and lost events. All UTMStack instances should share the same consumer group so they can process events together." - }, - "createStorageAccount": { - "title": "Create a Storage Account", - "body": "UTMStack needs a Storage Account to checkpoint its read position. Create one in the same region as the Event Hub.", - "docLabel": "Quickstart: Create a storage account" - }, - "storageContainer": { - "title": "Get the Storage Container name", - "body": "Get the Storage Container name in: All services → Storage accounts → your account → Containers. You will use it to configure your config group below." - }, - "storageConnection": { - "title": "Copy the Storage Account connection string", - "body": "Get the Storage Account connection string with key in: All services → Storage accounts → your account → Access keys. UTMStack uses it to store Event Hub checkpoints." - }, - "eventGrid": { - "title": "Register the Event Grid resource provider", - "body": "Configure your subscription to send logs to the Event Hub. Go to Subscriptions → Resource providers, search for Event Grid (Microsoft.EventGrid) and make sure it is registered." - }, - "createEventSubscription": { - "title": "Create an Event Subscription", - "body": "In the subscription Events panel, create a new event by clicking Events → Event Subscription." - }, - "configureEventSubscription": { - "title": "Point the Event Subscription at your Event Hub", - "body": "Configure the Event Subscription to send logs to the Event Hub you created in step 1." - } - }, - "sampleLabel": "Sample connection string:", - "credentials": { - "title": "Event Hub configuration", - "body": "Use the data collected in the steps above to configure UTMStack. You can add more than one Event Hub by saving additional configurations.", - "mapping": { - "intro": "Field reference", - "eventHubConnection": "Event Hub connection string — value obtained in step 3", - "consumerGroup": "Consumer group — value obtained in step 4", - "storageContainer": "Storage container name — value obtained in step 6", - "storageConnection": "Storage account connection string — value obtained in step 7" - } - }, - "fields": { - "eventHubConnection": { - "label": "Event Hub connection string" - }, - "consumerGroup": { - "label": "Consumer group" - }, - "storageContainer": { - "label": "Storage container name" - }, - "storageConnection": { - "label": "Storage account connection string" - } - } - }, - "aws": { - "intro": { - "title": "How it works", - "body": "UTMStack reads audit activity directly from AWS CloudWatch Logs. CloudTrail captures API calls and management events across your AWS account, forwards them to a CloudWatch log group, and UTMStack polls that group to ingest and correlate events.", - "diagram": { - "source": "API events", - "edge1": "CloudTrail", - "cloudwatchSub": "log groups", - "edge2": "polls", - "utmstackSub": "alerts & correlation" - }, - "note": "No agent is installed on AWS — UTMStack pulls log events using read-only IAM credentials you provide below." - }, - "iamSection": "Configure IAM User", - "iam": { - "dashboard": { - "title": "Open the IAM dashboard", - "body": "Open the AWS console, navigate to the IAM dashboard and select Users." - }, - "addUser": { - "title": "Add a user", - "body": "Click Add user, enter a descriptive user name, and proceed to the next step." - }, - "attachPolicy": { - "title": "Attach the read-only policy", - "body": "Under Permissions, attach the required policy. Select CloudWatchLogsReadOnlyAccess for read-only CloudWatch access." - }, - "createUser": { - "title": "Create the user", - "body": "Review the configuration and click Create user to provision the account." - }, - "openUser": { - "title": "Open the new user", - "body": "Open the newly created user by clicking its name to view details and manage credentials." - }, - "securityTab": { - "title": "Go to Security credentials", - "body": "Select the Security credentials tab to create programmatic access keys." - }, - "createKey": { - "title": "Create an access key", - "body": "Click Create access key and choose the option for an application running outside AWS (programmatic access)." - }, - "confirmKey": { - "title": "Confirm creation", - "body": "Confirm creation of the access key. AWS will generate an Access Key ID and Secret Access Key." - }, - "downloadKey": { - "title": "Save your credentials", - "body": "Download the credentials file or copy the Access Key ID and Secret Access Key to a secure location — the Secret Access Key is only shown once." - } - }, - "credentials": { - "title": "Enter credentials", - "body": "Paste the Access Key ID and Secret Access Key obtained in the previous steps. UTMStack verifies the credentials against AWS before saving." - }, - "cloudwatchSection": "Configure AWS CloudWatch", - "cloudwatch": { - "createGroup": { - "title": "Create a CloudWatch Log Group", - "body": "Open the CloudWatch console, choose Log management and click Create log group." - }, - "nameGroup": { - "title": "Name the log group and set retention", - "body": "Enter the log group name utmstack and set retention to 1 day. Click Create log group." - }, - "openTrail": { - "title": "Open CloudTrail and create a trail", - "body": "In the CloudTrail console click Create trail to begin configuring a new trail." - }, - "configureTrail": { - "title": "Configure delivery, validation and CloudWatch integration", - "body": "On the CloudTrail creation form set the following options:", - "items": [ - "Trail name and scope: enter a descriptive name; enable Apply trail to all accounts in my organization if you need org-wide collection.", - "S3 destination: choose Create new S3 bucket (or select an existing bucket) for raw log delivery.", - "Encryption: enable Log file SSE-KMS and select the appropriate KMS key.", - "Log file validation: enable to ensure integrity of delivered logs (recommended).", - "CloudWatch Logs: enable delivery to CloudWatch, select Use existing log group and enter the exact name utmstack.", - "IAM role: provide or create the role CloudTrail will assume to write to S3 and publish to CloudWatch." - ] - }, - "eventTypes": { - "title": "Select event types", - "body": "Enable the event categories required for monitoring and auditing.", - "management": { - "label": "1 · Management events", - "body": "Enable Management events and select All to record all API activity that manages AWS resources (create, update, delete)." - }, - "data": { - "label": "2 · Data events", - "body": "Add a Data event. Choose S3 and select Log all events to capture object-level operations such as GetObject and PutObject." - }, - "network": { - "label": "3 · Network activity events", - "body": "In the Network Activities section add at least one service (e.g. ec2.amazonaws.com) and enable Log all events." - } - }, - "review": { - "title": "Review and create the trail", - "body": "On the Configure event aggregation screen accept the defaults (or adjust if required). Review all settings and click Create trail." - } - }, - "fields": { - "accessKeyId": { - "label": "AWS access key ID" - }, - "secretAccessKey": { - "label": "AWS secret access key" - }, - "region": { - "label": "AWS default region" - }, - "logGroupName": { - "label": "Log group name" - } - } - }, - "crowdstrike": { - "intro": { - "title": "How it works", - "body": "UTMStack reads detections and audit activity directly from the CrowdStrike Falcon Event Streams API. You create an API client in Falcon with Event Streams scope; UTMStack runs an internal puller that streams events using those credentials. Nothing is installed on your endpoints or in Falcon.", - "diagram": { - "source": "detections & events", - "edge1": "Event Streams API", - "api": "Falcon API", - "apiSub": "event stream", - "edge2": "pulls", - "utmstackSub": "alerts & correlation" - }, - "note": "No agent is deployed by UTMStack — it pulls events from Falcon using the read-only API client credentials you provide below." - }, - "sections": { - "apiClients": { - "title": "Open API Clients and Keys", - "body": "In the Falcon console, open the menu (hamburger icon, top-left) and go to Support and resources → API Clients and Keys." - }, - "createClient": { - "title": "Create a new API client", - "body": "Click Create API Client to start a new client definition." - }, - "scopes": { - "title": "Name the client and grant Event Streams scope", - "body": "Give the client a descriptive name (UTMStack uses it to identify the event source) and select the API scopes required for Event Streams. Click Create to generate the credentials." - }, - "recordCredentials": { - "title": "Record the credentials", - "body": "Copy the Client ID, Client Secret and the Base URL for your CrowdStrike region. The secret is shown only once — store it securely. You will paste all three into the form below." - } - }, - "credentials": { - "title": "API client configuration", - "body": "Use the credentials from the steps above to configure UTMStack. You can add more than one CrowdStrike client by saving additional configurations.", - "mapping": { - "intro": "Field reference", - "appName": "App name — the descriptive client name from step 3 (identifies the event source)", - "clientId": "Client ID — value recorded in step 4", - "clientSecret": "Client Secret — value recorded in step 4 (shown only once)", - "cloudRegionUrl": "Base URL — your region endpoint, e.g. https://api.crowdstrike.com (us-1), https://api.us-2.crowdstrike.com (us-2), https://api.eu-1.crowdstrike.com (eu-1)" - } - }, - "fields": { - "appName": { - "label": "App name" - }, - "clientId": { - "label": "Client ID" - }, - "clientSecret": { - "label": "Client Secret" - }, - "cloudRegionUrl": { - "label": "Base URL (cloud region)" - } - } - } - }, - "custom": { - "intro": { - "title": "How it works", - "body": "A custom integration ingests logs from any source the built-in modules do not cover. You install the UTMStack Collector, register a listener for your data with the protocol of your choice, and point your source at it.", - "note": "Pick the protocol your source can send (syslog UDP/TCP/TLS, or HTTP/HTTPS for JSON) below — the Collector creates the data type automatically." - }, - "diagram": { - "source": "Your source", - "sourceSub": "any app or device", - "forwarder": "Collector", - "ingests": "ingests", - "utmstackSub": "alerts & correlation" - }, - "choose": { - "title": "Choose protocol and port", - "body": "Select how your source sends data and the port the Collector should listen on, then run the activation command on the Collector host.", - "portLabel": "Listener port", - "tlsFirst": "First load your TLS certificate and key on the Collector:", - "enableLabel": "Then enable the integration:", - "authNote": "To require authentication, append --auth bearer (token) or --auth hmac — the Collector prints a token to use in the Authorization header." - }, - "send": { - "title": "Point your source at the Collector", - "bodyNetwork": "Configure your source to send {{proto}} syslog to {{host}}:{{port}}. Most devices have a remote-syslog or log-forwarding setting for this.", - "bodyHttp": "Send your events as JSON via HTTP POST to {{endpoint}}. Each request body is one JSON event:", - "httpBindNote": "The HTTP/HTTPS listener binds to 127.0.0.1 (the Collector host) by default, so post from an app running on that host — or front it with a reverse proxy. For remote sources, use syslog (UDP/TCP/TLS)." - }, - "parserTitle": "Parsing", - "parserBody": "Incoming events are stored under the {{dataType}} data type. Add a parsing filter for it so the raw payload is mapped into structured fields, then build alert rules on top.", - "manualCommand": { - "title": "Optional — Enable via the command line instead", - "intro": "Prefer the terminal? SSH into the Collector host and run the command below — it matches whatever protocol and port you have selected above." - }, - "whenTitle": "When to use this", - "whenBody": "Use this when your source is not in the catalog. Forward syslog or arbitrary JSON to UTMStack and set a parser to normalize the fields.", - "endpointsTitle": "Endpoints", - "syslogUdp": "Syslog (UDP)", - "syslogTls": "Syslog (TLS)", - "httpJson": "HTTP / JSON", - "payloadTitle": "Sample JSON payload", - "openEditor": "Open parser editor", - "powershellLabel": "PowerShell (run as administrator)", - "linuxLabel": "Linux — bash", - "macosLabel": "macOS — bash", - "exampleLabel": "Example syslog target on {{name}}:" - }, - "remoteEnable": { - "title": "Enable this integration remotely", - "body": "Pick a Collector, choose the protocol and port, then enable the integration — no SSH needed.", - "noPermission": "You don't have permission to manage remote integrations. Ask an administrator to grant the integrations.write permission.", - "loadingCollectors": "Loading Collectors…", - "noCollectors": "No Collector is registered yet. Install one above to enable integrations remotely.", - "forwarderOffline": "This Collector is offline and can't receive configuration changes right now.", - "legendOnline": "{{count}} online", - "legendOffline": "{{count}} offline", - "legendTotal": "{{count}} total", - "forwarderLabel": "Collector", - "protoLabel": "Protocol", - "portLabel": "Port", - "currentStateLoading": "Checking current configuration…", - "currentlyEnabled": "Currently: enabled · {{proto}} · port {{port}}", - "currentlyDisabled": "Currently: disabled · {{proto}} · port {{port}}", - "authLabel": "Authentication", - "authNone": "None", - "authBearer": "Bearer token", - "authHmac": "HMAC signature", - "pathLabel": "Path", - "signatureHeaderLabel": "Signature header", - "certTitle": "TLS certificate", - "certLoading": "Checking certificate status…", - "certLoaded": "A valid certificate is already loaded on this Collector.", - "certMissing": "No certificate loaded yet — upload one to enable this protocol.", - "certInvalid": "The loaded certificate is invalid: {{error}}", - "certPemLabel": "Certificate", - "keyPemLabel": "Private key", - "caPemLabel": "CA certificate", - "uploadCertsButton": "Upload certificate", - "certUploadSuccess": "Certificate uploaded.", - "certUploadError": "Failed to upload the certificate.", - "certReadError": "Could not read the selected file(s).", - "enableButton": "Enable integration", - "disableButton": "Disable integration", - "enableSuccess": "Integration enabled.", - "disableSuccess": "Integration disabled.", - "enableError": "Failed to update the integration.", - "secretWarning": "Store this token securely — it won't be shown again.", - "sendToInstance": "Send to instance", - "enterpriseFeature": "This is an Enterprise feature.", - "addCollector": "Add Collector", - "addApiKey": "Add API key", - "apiKeyLabel": "API key", - "apiKeyHint": "First you'll need an API key.", - "apiKeyPlaceholder": "Select an API key", - "apiKeyAddNew": "Add API key…", - "apiKeyNone": "No API keys yet", - "forwarderNoRemoteControl": "This forwarder was installed with remote control disabled. It ignores configuration sent from here, which can only be changed on the machine itself." - } - }, - "codeBlock": { - "copy": "Copy", - "copied": "Copied" - }, - "createDrawer": { - "title": "New custom integration", - "moduleName": "Module name", - "moduleNameHint": "Unique identifier. No spaces.", - "moduleNamePlaceholder": "my-custom-app", - "prettyName": "Display name", - "prettyNamePlaceholder": "My Custom App", - "dataType": "Data type", - "dataTypePlaceholder": "Unique identifier for this data type", - "icon": "Icon", - "iconHint": "PNG, SVG, JPEG, GIF or WEBP. Max 3MB. Used as the integration logo.", - "iconPreview": "Icon preview", - "dataTypeExists": "This data type already exists", - "invalidFileType": "Icon must be a valid image file (PNG, JPEG, SVG, GIF, WEBP)", - "fileTooLarge": "Icon must not exceed 3MB", - "fileReadError": "Failed to read file", - "cancel": "Cancel", - "create": "Create integration", - "creating": "Creating…", - "editTitle": "Edit integration", - "save": "Save", - "saving": "Saving…", - "currentIcon": "Current icon — upload a file to replace it", - "name": "Integration name", - "namePlaceholder": "e.g. Acme Firewall", - "description": "Description", - "descriptionPlaceholder": "What this integration ingests and why (optional)", - "identifierHint": "Stored as “{{id}}” (derived from the name)", - "nameTaken": "That integration name can’t be used — an integration with that identifier already exists.", - "removeIcon": "Remove icon", - "defaultIconNote": "Default icon — upload a file to use your own." - }, - "toast": { - "created": "Integration created", - "updated": "Integration updated", - "updateError": "Failed to update integration" - }, - "delete": { - "title": "Delete integration", - "confirm": "Delete this integration?", - "yes": "Delete", - "no": "Cancel", - "deleted": "Integration deleted", - "error": "Failed to delete integration" - }, - "modules": { - "WINDOWS_AGENT": "Collect Windows system, security and event-log activity through the lightweight UTMStack agent installed on each host.", - "LINUX_AGENT": "Collect Linux system, authentication and audit logs through the lightweight UTMStack agent installed on each host.", - "MACOS": "Collect macOS system and security log activity from Apple Mac endpoints through the lightweight UTMStack agent.", - "VMWARE": "Ingest VMware ESXi hypervisor syslog so virtualization-host activity and events are monitored within UTMStack.", - "NETFLOW": "Ingest NetFlow records from routers and switches to monitor network-traffic patterns and detect traffic anomalies.", - "AWS_IAM_USER": "Ingest AWS account activity and API calls via CloudTrail and CloudWatch to audit cloud usage, access and changes.", - "AZURE": "Ingest Microsoft Azure platform and activity logs to monitor cloud workloads, identity and resource changes.", - "O365": "Ingest Microsoft 365 audit logs across Exchange, Teams, SharePoint and OneDrive to monitor user and admin activity.", - "O365_GRAPH": "Ingest Microsoft Graph security events — alerts, incidents, directory audit, sign-ins, risk detections and Purview audit logs — to monitor identity and threat activity across your tenant.", - "GCP": "Ingest Google Cloud Platform audit and activity logs to monitor compute, storage and identity across projects.", - "KASPERSKY": "Ingest Kaspersky Security Center detections and endpoint telemetry to correlate malware activity across the network.", - "ESET": "Ingest ESET PROTECT endpoint detections and telemetry to correlate multilayered malware defense across your estate.", - "BITDEFENDER": "Ingest Bitdefender GravityZone detections and endpoint telemetry to correlate threats across business devices.", - "SENTINEL_ONE": "Ingest SentinelOne endpoint detections and behavioral telemetry to correlate and investigate threats at scale.", - "SOPHOS": "Ingest Sophos Central detections across endpoint, server, firewall and email to correlate threats in one place.", - "CROWDSTRIKE": "Ingest CrowdStrike Falcon endpoint and workload detections to correlate cloud-native threat activity in UTMStack.", - "CISCO": "Ingest Cisco ASA firewall traffic, VPN and threat logs to monitor perimeter security and access within UTMStack.", - "MERAKI": "Ingest Cisco Meraki firewall and security-appliance syslog to monitor cloud-managed network traffic and threats.", - "FIRE_POWER": "Ingest Cisco Firepower NGFW and IPS logs to monitor intrusion attempts and threat activity at the perimeter.", - "CISCO_SWITCH": "Ingest Cisco switch syslog and telemetry to monitor network performance, configuration changes and security.", - "FORTIGATE": "Ingest Fortinet FortiGate NGFW traffic and threat logs to monitor perimeter security and network activity.", - "FORTIWEB": "Ingest Fortinet FortiWeb WAF logs to monitor web-application attacks and protect exposed services and APIs.", - "SOPHOS_XG": "Ingest Sophos XG firewall logs covering web filtering, IPS and VPN to monitor network traffic and threats.", - "PALO_ALTO": "Ingest Palo Alto Networks NGFW traffic and threat logs to monitor application usage and perimeter security.", - "SONIC_WALL": "Ingest SonicWall NGFW traffic and threat logs to monitor perimeter security and network activity in UTMStack.", - "PFSENSE": "Ingest pfSense firewall and router logs with unified threat management to monitor network traffic and threats.", - "MIKROTIK": "Ingest MikroTik RouterOS firewall, routing and wireless logs to monitor network activity and configuration.", - "AIX": "Collect IBM AIX Unix system, security and audit logs to monitor activity on IBM Power platforms within UTMStack.", - "AS_400": "Collect IBM AS/400 (IBM i) system and audit journals to monitor user activity on midrange OS/400 platforms.", - "ORACLE": "Ingest Oracle Database audit logs to monitor queries, access and privileged activity across your databases.", - "SURICATA": "Ingest Suricata IDS/IPS alerts and network events to detect intrusions and malicious traffic across the network.", - "DECEPTIVE_BYTES": "Ingest Deceptive Bytes alerts from its active endpoint-deception platform to surface attacker activity early.", - "GITHUB": "Ingest GitHub audit logs to monitor repository access, code changes and organization activity for source security.", - "UTMSTACK": "Ingest UTMStack's own SIEM and XDR telemetry to monitor platform health, internal activity and self-audit events.", - "NGINX": { - "name": "Nginx", - "description": "Ingest Nginx access and error logs to monitor web-serving activity, reverse-proxy traffic and client requests." - }, - "APACHE": { - "name": "Apache", - "description": "Ingest Apache HTTPD access and error logs to monitor web-serving activity and client requests." - }, - "APACHE2": { - "name": "Apache2", - "description": "Ingest Apache2 (HTTPD) web server logs to monitor request handling, errors and access on Linux hosts." - }, - "IIS": { - "name": "IIS", - "description": "Ingest Internet Information Services (IIS) access and log-file activity to monitor Windows web serving." - }, - "MYSQL": { - "name": "MySQL", - "description": "Ingest MySQL database log activity to monitor queries, authentication and data-store access." - }, - "POSTGRESQL": { - "name": "PostgreSQL", - "description": "Ingest PostgreSQL database logs to monitor queries, access and activity across your data stores." - }, - "MONGODB": { - "name": "MongoDB", - "description": "Ingest MongoDB log activity to monitor document-database access, queries and application behavior." - }, - "REDIS": { - "name": "Redis", - "description": "Ingest Redis log and telemetry activity to monitor in-memory data store usage and real-time workloads." - }, - "ELASTICSEARCH": { - "name": "Elasticsearch", - "description": "Ingest Elasticsearch logs to monitor the search and analytics engine and its application workloads." - }, - "LOGSTASH": { - "name": "Logstash", - "description": "Ingest Logstash pipeline logs to monitor the data-processing pipeline and its event transformations." - }, - "KIBANA": { - "name": "Kibana", - "description": "Ingest Kibana logs to monitor the data-visualization and exploration layer and its usage." - }, - "KAFKA": { - "name": "Apache Kafka", - "description": "Ingest Apache Kafka logs to monitor real-time streaming pipelines, brokers and message flow." - }, - "NATS": { - "name": "NATS", - "description": "Ingest NATS messaging logs to monitor the message bus, connectivity and event delivery." - }, - "HAPROXY": { - "name": "HAProxy", - "description": "Ingest HAProxy logs to monitor load balancing, proxy traffic and network availability." - }, - "TRAEFIK": { - "name": "Traefik", - "description": "Ingest Traefik logs to monitor routing, load balancing and proxy traffic across workloads." - }, - "OSQUERY": { - "name": "osquery", - "description": "Ingest OsQuery logs to monitor endpoint state, queries and system inventory via SQL-style requests." - }, - "SYSLOG": { - "name": "Syslog", - "description": "Send syslog (RFC 5424/3164) from any device or application to the collector endpoint for central log intake." - }, - "JSON": { - "name": "JSON Input", - "description": "Send JSON log payloads to the ingestion endpoint for structured event intake from applications and scripts." - }, - "WINDOWS_SQL_SERVER": { - "name": "SQL Server Event Logs", - "description": "Collect Microsoft SQL Server audit and event records through the Windows Event Log and UTMStack agent." - }, - "WINDOWS_FILE_AUDITING": { - "name": "Windows File Access Auditing", - "description": "Collect Windows file access audit events through the Windows Event Log and UTMStack agent." - }, - "ELASTICsearch": { - "name": "ELASTICsearch", - "description": "Ingesta los registros de Elasticsearch para monitorear el motor de búsqueda y análisis y sus cargas de trabajo de aplicación." - } - }, - "edit": { - "title": "Edit integration" - }, - "allCategories": "All categories", - "customOnly": "Custom" - }, - "dataProcessing": { - "title": "Data processing", - "subtitle": "Ingestion and processing statistics: events received, dropped by stage, and the top sources and types.", - "ingestion": { - "title": "Ingestion", - "last24h": "last 24 hours", - "noData": "No data in this window.", - "loadError": "Could not load ingestion stats.", - "groupBy": { - "dataSource": "By data source", - "dataType": "By data type" - }, - "status": { - "received": "Received", - "parsing_dropped": "Dropped (parsing)", - "analysis_dropped": "Dropped (analysis)", - "correlation_dropped": "Dropped (correlation)", - "all": "All events" - } - }, - "filters": { - "title": "Filters", - "new": "New filter", - "search": "Search by path…", - "refresh": "Refresh", - "retry": "Retry", - "empty": "No filters match.", - "loadError": "Could not load filters.", - "toggleError": "Could not change the filter state", - "system": "System", - "custom": "Custom", - "systemReadonly": "System filters are read-only", - "view": "View", - "edit": "Edit", - "ownership": { - "all": "All", - "system": "System", - "custom": "Custom" - }, - "state": { - "all": "All", - "active": "Active", - "inactive": "Inactive" - }, - "col": { - "filter": "Filter", - "type": "Type", - "active": "Active", - "actions": "Actions" - }, - "pageInfo": "{{from}}–{{to}} of {{count}}" - }, - "editor": { - "createTitle": "New filter", - "editTitle": "Edit filter", - "viewTitle": "View filter", - "relPath": "Path", - "relPathHint": "Folder + file, e.g. syslog/my-filter.yaml", - "content": "Pipeline (YAML)", - "contentHint": "Steps run in order: grok, rename, delete, dynamic plugins, …", - "save": "Save", - "saving": "Saving…", - "saved": "Filter saved", - "saveError": "Could not save the filter", - "cancel": "Cancel", - "delete": "Delete", - "deleteConfirm": "Delete this filter?", - "deleted": "Filter deleted", - "deleteError": "Could not delete the filter" - }, - "kpi": { - "received": "Received", - "dropped": "Dropped", - "dropRate": "{{rate}}% drop rate", - "stored": "Stored", - "throughput": "Throughput", - "perMin": "{{value}}/min", - "survival": "{{rate}}% kept" - }, - "section": { - "overTime": "Events over time", - "top": "Top", - "dropReasons": "Drop reasons" - }, - "live": { - "auto": "Auto" - }, - "pipeline": { - "title": "Ingestion pipeline", - "stages": { - "received": "Received", - "parsed": "Parsed", - "analyzed": "Analyzed", - "stored": "Stored" - } - }, - "chart": { - "title": "Throughput over time", - "received": "Received", - "dropped": "Dropped" - }, - "donut": { - "title": "Drop composition", - "dropped": "dropped" - }, - "breakdown": { - "title": "Top sources & types", - "bars": "Bars", - "treemap": "Treemap", - "showAll": "Show all {{count}}", - "showLess": "Show less", - "lastSeen": "Last seen", - "ago": "{{time}} ago" - } - }, - "datasources": { - "limitBanner": { - "title": "Datasource limit exceeded.", - "message": "You have {{count}} datasources but your license covers {{limit}}. Logs from datasources beyond the limit are being dropped.", - "cta": "Manage license", - "dismiss": "Dismiss" - }, - "title": "Data sources", - "total": "{{count}} total", - "subtitle": "Agents, integrations and direct sources feeding events. Status is derived from the last time each source was seen.", - "connectSource": "Connect a source", - "loading": "Loading data sources…", - "loadFailed": "Could not load data sources.", - "retry": "Retry", - "none": "No data sources match this view.", - "ingestion": { - "title": "Ingestion", - "received": "events received", - "none": "No ingestion in the last 24 hours.", - "ago24h": "24h ago", - "now": "now" - }, - "usage": { - "title": "Data sources", - "ofUnlimited": "of unlimited", - "ofLimit": "of {{limit}}", - "overLimit": "Over the licensed limit — data beyond the cap is at risk.", - "configured": "configured" - }, - "tabs": { - "all": "All", - "agent": "Agents", - "puller": "Integrations", - "direct": "Direct", - "offline": "Offline" - }, - "toolbar": { - "searchPlaceholder": "Search by name…", - "list": "List", - "cards": "Cards", - "refresh": "Refresh" - }, - "labels": { - "filteredBy": "Filtered by label", - "add": "Add label…", - "addFirst": "Add a label…", - "hint": "Type a label and press Enter to add it. Changes save automatically." - }, - "status": { - "live": "Live", - "idle": "Idle", - "offline": "Offline" - }, - "kind": { - "agent": "Agent", - "puller": "Integration", - "direct": "Direct" - }, - "cols": { - "source": "Source", - "type": "Type", - "status": "Status", - "events24h": "Events 24h", - "lastSeen": "Last seen" - }, - "time": { - "justNow": "just now", - "minutesAgo": "{{count}}m ago", - "hoursAgo": "{{count}}h ago", - "daysAgo": "{{count}}d ago" - }, - "drawer": { - "loading": "Loading…", - "loadFailed": "Could not load the data source.", - "statsIdentity": "Stats & identity", - "metadata": "Metadata", - "labelsSection": "Labels", - "dangerZone": "Danger zone", - "rows": { - "events24h": "Events 24h", - "lastSeen": "Last seen", - "discovered": "Discovered", - "kind": "Kind", - "dataType": "Data type", - "ip": "IP", - "id": "ID" - }, - "dangerText": "Deleting removes this source from the registry. Historical events stay searchable in the Log Explorer; if the source keeps sending data it will be rediscovered.", - "delete": "Delete data source", - "confirmDelete": "Confirm delete", - "cancel": "Cancel", - "viewLogs": "View logs", - "trend": "Ingestion trend", - "noTrend": "No events received in this window", - "logGap": "Last event {{since}} — possible log gap" - }, - "toast": { - "labelsUpdated": "Labels updated", - "labelsFailed": "Failed to update labels", - "deleted": "Data source deleted", - "deleteFailed": "Failed to delete" - }, - "console": { - "section": "Console", - "sectionHint": "Run commands on this host through its agent (live response).", - "open": "Open console", - "close": "Close", - "hint": "Type a command and press Enter to run it on the agent.", - "running": "Running…", - "placeholder": "Type a command…", - "offline": "This agent appears offline — it may not respond to commands.", - "vars": { - "button": "Variables", - "title": "Command variables", - "subtitle": "Reference these in commands as", - "add": "New variable", - "name": "Name", - "value": "Value", - "description": "Description", - "isSecret": "Secret (encrypted, masked in output)", - "secret": "secret", - "secretHint": "Leave blank to keep the stored value.", - "save": "Save", - "cancel": "Cancel", - "edit": "Edit", - "delete": "Delete", - "loading": "Loading…", - "empty": "No variables yet.", - "saved": "Variable saved", - "deleted": "Variable deleted", - "nameRequired": "Name is required", - "loadError": "Failed to load variables", - "saveError": "Failed to save variable", - "deleteError": "Failed to delete variable", - "insert": "Insert", - "valueRequired": "A value is required" - }, - "disabled": "Agent offline — commands are disabled", - "connError": "Connection error", - "cmdError": "Command error", - "shellSelect": "Shell type", - "noRemoteControl": "This agent was installed with remote control disabled. It refuses commands, and that can only be changed on the machine itself.", - "noRemoteControlShort": "Remote control disabled on this agent", - "password": { - "title": "Authentication", - "hint": "Authenticate to run commands on this agent.", - "tfaPrompt": "Code: ", - "confirm": "OK", - "cancel": "Cancel", - "authError": "Authentication failed", - "authHint": "Authenticate to run commands on this agent.", - "authOk": "Authenticated." - } - }, - "sensitivity": { - "section": "Asset sensitivity", - "hint": "Business criticality (CIA, 0–3) of this asset. Alerts targeting its host/IP are weighted by these values.", - "saved": "Sensitivity updated", - "failed": "Failed to update sensitivity", - "save": "Save", - "confidentiality": "Confidentiality", - "integrity": "Integrity", - "availability": "Availability", - "levels": { - "0": "None", - "1": "Low", - "2": "Medium", - "3": "High" - } - }, - "health": { - "online": "online", - "offline": "offline", - "total": "total" - } - }, - "adversaries": { - "title": "Adversary view", - "subtitle": "Every IP, host or user seen attacking your environment, with their techniques and targets.", - "countChip": "{{count}} adversaries", - "refresh": "Refresh", - "search": "Search by IP, host, user, country, ASO…", - "empty": "No adversaries match.", - "loadError": "Could not load adversaries.", - "retry": "Retry", - "views": { - "all": "All", - "high": "High severity", - "ip": "IPs", - "host": "Hosts", - "user": "Users" - }, - "threat": { - "critical": "Critical", - "high": "High", - "medium": "Medium", - "low": "Low" - }, - "kind": { - "ip": "IP", - "host": "Host", - "user": "User" - }, - "layout": { - "list": "List", - "cards": "Cards" - }, - "overview": { - "title": "Adversary activity · last 24 hours", - "high": "high severity", - "countries": "countries", - "alerts": "alerts", - "ago24": "24h ago", - "ago12": "12h ago", - "now": "now" - }, - "col": { - "adversary": "Adversary", - "threat": "Threat", - "alerts": "Alerts", - "targets": "Targets", - "lastSeen": "Last seen", - "victims": "Victims" - }, - "card": { - "alerts": "Alerts", - "techniques": "Techniques", - "targets": "Targets" - }, - "tabs": { - "profile": "Profile", - "techniques": "Techniques", - "targets": "Targets", - "alerts": "Alerts" - }, - "drawer": { - "activity": "Activity over 24 hours", - "identification": "Identification", - "kindLabel": "Type", - "identifier": "Identifier", - "firstSeen": "First seen", - "lastSeen": "Last seen", - "geolocation": "Geolocation", - "country": "Country", - "city": "City", - "topTechniques": "Top techniques", - "noTechniques": "No techniques recorded.", - "targets": "Targets", - "noTargets": "No targets recorded.", - "recentAlerts": "Recent alerts", - "noAlerts": "No alerts.", - "echoes": "{{count}} echoes" - }, - "relative": { - "justNow": "just now", - "minutesAgo": "{{count}}m ago", - "hoursAgo": "{{count}}h ago", - "daysAgo": "{{count}}d ago" - }, - "field": { - "ip": "IP", - "host": "Host", - "user": "User", - "port": "Port", - "domain": "Domain", - "mac": "MAC", - "country": "Country", - "city": "City", - "asn": "ASN", - "aso": "ASO" - } - }, - "timeRange": { - "quick": "Quick ranges", - "relative": "Relative", - "absolute": "Absolute", - "last": "Last", - "apply": "Apply", - "allTime": "All time", - "from": "From", - "to": "To", - "now": "now", - "units": { - "minutes": "minutes", - "hours": "hours", - "days": "days", - "weeks": "weeks", - "months": "months" - }, - "presets": { - "15m": "Last 15 minutes", - "1h": "Last 1 hour", - "6h": "Last 6 hours", - "24h": "Last 24 hours", - "7d": "Last 7 days", - "30d": "Last 30 days" - } - }, - "socAi": { - "title": "SOC-AI Configuration", - "subtitle": "Configure the AI agent that triages alerts and powers the operations assistant.", - "section": { - "connection": "Model & connection", - "auth": "Authentication", - "behavior": "Alert triage behavior", - "advanced": "Advanced" - }, - "usage": { - "title": "Usage", - "chat": "Chat completions (today)", - "unavailable": "Usage isn't available yet.", - "resetsIn": "Resets in {{time}}" - }, - "provider": { - "label": "Provider", - "hint": "Selects the wire format. Anything other than Anthropic uses the OpenAI-compatible API." - }, - "model": { - "label": "Model", - "hint": "Model identifier exposed by the provider.", - "customOption": "Custom model…", - "customPlaceholder": "Enter a model ID" - }, - "url": { - "label": "API URL", - "hint": "Leave empty to use the provider's default endpoint." - }, - "apiKey": { - "label": "API key", - "hint": "Credential sent to the provider.", - "setHint": "A key is stored. Leave blank to keep it." - }, - "authType": { - "label": "Authentication type", - "hint": "How credentials are sent to your gateway.", - "options": { - "apiKey": "API Key", - "bearer": "Bearer", - "customHeaders": "Custom Headers", - "none": "None" - } - }, - "authHeaderName": { - "label": "Auth header name", - "hint": "Header carrying the key (e.g. api-key for Azure)." - }, - "authToken": { - "label": "Bearer token", - "hint": "Credential sent to the provider.", - "setHint": "A token is stored. Leave blank to keep it." - }, - "customHeaders": { - "label": "Custom headers", - "hint": "Extra headers sent with every request. Values are encrypted; \"*****\" keeps the stored one.", - "keyPlaceholder": "Header name", - "valuePlaceholder": "Value", - "addRow": "Add header", - "remove": "Remove header" - }, - "maxTokens": { - "label": "Max tokens", - "hint": "Maximum tokens per LLM response." - }, - "maxToolIterations": { - "label": "Max tool iterations", - "hint": "Cap on the agent's plan -> tool -> observe loop." - }, - "autoAnalyze": { - "label": "Auto-analyze alerts", - "hint": "Triage incoming alerts in real time." - }, - "allowIncidents": { - "label": "Allow managing incidents", - "hint": "The triage agent may create or update incidents when it decides an alert warrants one." - }, - "changeAlertStatus": { - "label": "Change alert status", - "hint": "Let the agent set an alert's status during triage." - }, - "automaticIncidentCreation": { - "label": "Create incidents", - "hint": "Let the agent open incidents from triaged alerts." - }, - "allowedWriteTools": { - "label": "Allowed write tools", - "hint": "One MCP tool name per line the triage agent may use (e.g. alerts.update_status). Notes are always allowed." - }, - "save": "Save configuration", - "saving": "Verifying & saving...", - "saved": "SOC-AI configuration saved", - "saveError": "Failed to save configuration", - "loadError": "Failed to load configuration", - "modelRequired": "Model is required", - "applyTags": { - "label": "Apply tags", - "hint": "Let the agent tag alerts during triage." - }, - "note": { - "azure": "Paste your full Azure deployment endpoint as the URL; the model is your deployment name. Auth uses the api-key header.", - "ollama": "Point the URL at your Ollama host. No API key is needed for a local instance.", - "custom": "Any OpenAI-compatible endpoint. Set the URL, auth and any extra headers your gateway needs.", - "threatwinds": "Uses your UTMStack license automatically — no API key needed. Billed through your ThreatWinds subscription." - }, - "chat": { - "title": "SOC Assistant", - "dashboardCreateTitle": "Dashboard builder", - "empty": "Ask anything about your alerts, detections or the console — I can investigate and act on the SIEM.", - "tryPrefix": "Try", - "suggestion": "how many open alerts, grouped by adversary?", - "placeholder": "Ask a question…", - "ask": "Ask", - "send": "Send", - "collapse": "Collapse", - "expand": "Expand", - "clear": "Clear conversation", - "close": "Close", - "copy": "Copy", - "copied": "Copied", - "errorGeneric": "Something went wrong.", - "errorUnreachable": "Failed to reach the assistant.", - "compacting": "Compacting context…", - "dashboardEditTitle": "Dashboard editor", - "editingDashboard": "Editing: {{name}}", - "soarEditTitle": "SOAR flow editor", - "soarCreateTitle": "Create SOAR flow", - "editingFlow": "Editing flow: {{name}}" - }, - "focus": { - "alert": "Alert", - "incident": "Incident", - "remove": "Stop sharing with the assistant" - }, - "inheritance": { - "inherited": "Following the instance default. Saving here gives this tenant its own configuration.", - "own": "This tenant has its own configuration.", - "revert": "Follow the instance default", - "reverting": "Reverting…", - "reverted": "Now following the instance default" - }, - "allowance": { - "title": "AI allowance today", - "ofLimit": "of {{limit}} requests", - "denied": "requests — the AI is not available to this tenant", - "hint": "Set by whoever runs the instance. It resets at midnight UTC." - } - }, - "alerts": { - "title": "Alerts", - "matching": "{{count}} matching", - "subtitle": "Triage what matters.", - "openNow": "open right now.", - "view": { - "alerts": "Alerts", - "overview": "Overview" - }, - "toolbar": { - "searchPlaceholder": "Search by alert name…", - "allSeverities": "All severities", - "export": "Export CSV", - "refresh": "Refresh" - }, - "severity": { - "high": "High", - "medium": "Medium", - "low": "Low" - }, - "status": { - "open": "Open", - "in_review": "In review", - "completed": "Completed", - "auto": "Automatic review" - }, - "statusTabs": { - "all": "All" - }, - "overview": { - "overTime": "Alerts over time", - "matchingAlerts": "matching alerts", - "noData": "No data.", - "bySeverity": "By severity", - "byStatus": "By status" - }, - "filters": { - "add": "Add filter", - "clearAll": "Clear all", - "filterValues": "Filter values…", - "loadingValues": "Loading values…", - "noValues": "No values found.", - "pickValue": "Pick a value to add the filter.", - "empty": "(empty)", - "cancel": "Cancel", - "addBtn": "Add" - }, - "ops": { - "CONTAIN": "contains", - "IS": "is", - "IS_NOT": "is not", - "EXIST": "exists", - "DOES_NOT_EXIST": "does not exist" - }, - "fields": { - "adversary_domain": "Adversary domain", - "adversary_geolocation_asn": "Adversary ASN", - "adversary_geolocation_aso": "Adversary ASO", - "adversary_geolocation_country": "Adversary country", - "adversary_host": "Adversary host", - "adversary_ip": "Adversary IP", - "adversary_url": "Adversary URL", - "adversary_user": "Adversary user", - "assignee": "Assignee", - "category": "Category", - "dataSource": "Sensor", - "dataType": "Data type", - "description": "Description", - "id": "ID", - "impactScore": "Risk", - "impact_availability": "Availability", - "impact_confidentiality": "Confidentiality", - "impact_integrity": "Integrity", - "incidentDetail_incidentName": "Incident name", - "incidentDetail_incidentId": "Incident id", - "isIncident": "Is incident", - "name": "Alert name", - "notes": "Notes", - "severity": "Severity", - "status": "Status", - "tags": "Tags", - "target_domain": "Target domain", - "target_geolocation_asn": "Target ASN", - "target_geolocation_aso": "Target ASO", - "target_geolocation_country": "Target country", - "target_host": "Target host", - "target_ip": "Target IP", - "target_url": "Target URL", - "target_user": "Target user", - "technique": "Technique" - }, - "tagFilter": { - "tags": "Tags", - "tag_one": "{{count}} tag", - "tag_other": "{{count}} tags", - "clearSelection": "Clear selection", - "noTags": "No tags" - }, - "bulk": { - "selected": "{{count}} selected", - "setStatus": "Set status", - "addTag": "Add tag", - "noTags": "No tags", - "addToIncident": "Add to incident", - "clear": "Clear" - }, - "tagEditor": { - "tag": "Tag", - "noTagsYet": "No tags yet", - "createTag": "Create tag", - "newTagName": "New tag name…", - "createApply": "Create and apply tag", - "save": "Save", - "cancel": "Cancel", - "edit": "Edit tag", - "delete": "Delete tag", - "createRule": "Create tagging rule with this tag", - "systemLocked": "System tag (locked)", - "alreadyExists": "That tag already exists.", - "color": "Color {{color}}" - }, - "table": { - "actions": "Actions", - "alert": "Alert", - "status": "Status", - "technique": "Technique", - "severity": "Severity", - "risk": "Risk", - "echoes": "Echoes", - "time": "Time", - "riskHint": "Risk score (0–100), colored by severity", - "source": "Source", - "adversary": "Adversary" - }, - "row": { - "createRuleFromAlert": "Create a tag from this alert", - "createIncident": "Create incident from this alert", - "viewIncident": "View incident details", - "assignedTo": "Assigned to {{user}}", - "echoesTooltip": "{{count}} echoes — click to expand", - "echoesEmpty": "No echoes recorded" - }, - "echoes": { - "title": "{{count}} echoes", - "close": "Close", - "empty": "No echoes recorded for this alert.", - "loadError": "Could not load echoes." - }, - "list": { - "loading": "Loading alerts…", - "loadError": "Could not load alerts.", - "retry": "Retry", - "empty": "No alerts match this view." - }, - "badge": { - "incident": "Incident", - "aiAssessed": "AI assessed" - }, - "drawer": { - "setStatus": "Set status", - "completeFalsePositive": "Complete + false positive", - "addToIncident": "Add to incident", - "partOfIncident": "Part of an incident", - "tabs": { - "summary": "Summary", - "parties": "Parties", - "events": "Events", - "history": "History" - }, - "section": { - "description": "Description", - "solution": "Solution", - "references": "References", - "details": "Details", - "yourNotes": "Your notes", - "notes": "Notes" - }, - "details": { - "severity": "Severity", - "risk": "Risk", - "category": "Category", - "technique": "Technique", - "sensor": "Sensor", - "dataType": "Data type", - "alertId": "Alert ID", - "statusNote": "Status note", - "assignee": "Assignee" - }, - "incidentDetail": { - "incident": "Incident", - "id": "ID", - "createdBy": "Created by", - "created": "Created" - }, - "notesPlaceholder": "Add investigation notes…", - "saveNotes": "Save notes", - "assignee": "Assign", - "assign": "Assign", - "unassign": "Unassign", - "unassigned": "Unassigned", - "loadingUsers": "Loading users…", - "observationLabel": "Observation", - "observationPlaceholder": "Add an observation…", - "cancel": "Cancel", - "continue": "Continue" - }, - "related": { - "sample": "A sample of up to ~11 events the engine stored on this alert. Use “View all related logs” for the full, uncapped set.", - "loadingEchoes": "Loading the events of its echoes…", - "sampleWithEchoes": "The events stored on this alert and on its {{count}} echoes ({{read}} read). Use “View all related logs” for the full, uncapped set.", - "empty": "No sampled events stored on this alert. Load the full correlated set in the Log Explorer.", - "viewAll": "View all related logs" - }, - "party": { - "source": "Source / target", - "adversary": "Adversary", - "noData": "No data.", - "ip": "IP", - "host": "Host", - "user": "User", - "domain": "Domain", - "country": "Country" - }, - "history": { - "empty": "No history recorded.", - "by": "by {{user}}", - "actions": { - "UPDATE_STATUS": "Status updated", - "UPDATE_TAGS": "Tags updated", - "UPDATE_NOTES": "Notes updated", - "UPDATE_SOLUTION": "Solution updated", - "MARK_AS_INCIDENT": "Marked as incident" - }, - "detail": { - "statusTo": "Status → {{status}}", - "tags": "Tags: {{tags}}", - "aiAdded": "AI assessment added", - "observationAdded": "Observation added", - "notesUpdated": "Notes updated" - } - }, - "ai": { - "title": "SOC AI assessment", - "risk": "{{risk}} risk", - "score": "{{score}}/100", - "generate": "Generate AI summary", - "hint": "SOC-AI investigates this alert and adds an assessment.", - "generating": "Analyzing the alert… this can take a minute.", - "ready": "AI summary ready", - "failed": "Could not generate the AI summary", - "slow": "The AI summary is taking longer than expected. It will show up on the alert when it is ready." - }, - "incident": { - "titleAdd_one": "Add {{count}} alert to an incident", - "titleAdd_other": "Add {{count}} alerts to an incident", - "new": "New incident", - "existing": "Existing incident", - "nameLabel": "Incident name", - "namePlaceholder": "e.g. Suspected Scattered Spider intrusion", - "descriptionLabel": "Description", - "descriptionPlaceholder": "Optional summary…", - "pickLabel": "Pick an incident", - "loading": "Loading…", - "selectPlaceholder": "Select an incident…", - "willLink_one": "{{count}} alert will be linked.", - "willLink_other": "{{count}} alerts will be linked.", - "cancel": "Cancel", - "create": "Create incident", - "add": "Add to incident" - }, - "toast": { - "statusUpdated": "Status updated", - "statusFailed": "Failed to update status", - "tagsUpdated": "Tags updated", - "tagsFailed": "Failed to update tags", - "tagCreateFailed": "Failed to create tag", - "tagUpdated": "Tag updated", - "tagUpdateFailed": "Failed to update tag", - "tagDeleted": "Tag deleted", - "tagDeleteFailed": "Failed to delete tag", - "notesSaved": "Notes saved", - "notesFailed": "Failed to save notes", - "exportFailed": "Failed to export CSV", - "noRelatedLogs": "No related logs found for this alert", - "relatedLogsFailed": "Failed to load related logs", - "incidentCreated": "Incident created", - "alertsAdded": "Alerts added to incident", - "incidentFailed": "Failed to save incident", - "assigned": "Alert assigned", - "unassigned": "Alert unassigned", - "assignFailed": "Could not update assignee", - "newAlertsToast_title": "New alerts", - "newAlertsToast_count_one": "{{count}} new alert", - "newAlertsToast_count_other": "{{count}} new alerts", - "newAlertsToast_view": "View" - } - }, - "taggingRules": { - "title": "Tagging Rules", - "subtitle": "Automatically tag alerts that match conditions.", - "new": "New rule", - "refresh": "Refresh", - "empty": "No tagging rules yet.", - "loadError": "Could not load tagging rules.", - "retry": "Retry", - "deleteConfirm": "Delete the rule \"{{name}}\"? Future alerts matching its conditions will stop being tagged.", - "toolbar": { - "search": "Search by rule name…", - "allTags": "All tags" - }, - "table": { - "rule": "Rule", - "tags": "Tags", - "conditions": "Conditions", - "modifiedBy": "Modified by", - "modifiedDate": "Modified" - }, - "drawer": { - "createTitle": "New tagging rule", - "edit": "Edit", - "delete": "Delete", - "save": "Save", - "create": "Create", - "cancel": "Cancel" - }, - "form": { - "basics": "Basics", - "name": "Rule name", - "namePlaceholder": "e.g. Internal SSH brute-force", - "description": "Description", - "descriptionPlaceholder": "Why this rule exists and what it tags.", - "tags": "Tags to apply", - "noTags": "No tags selected.", - "addTag": "Add tag", - "removeTag": "Remove", - "noCatalog": "No tags in the catalog yet.", - "createTag": "Create tag", - "newTagName": "New tag name", - "conditions": "Conditions (ALL must match)", - "noConditions": "At least one condition is required.", - "addCondition": "Add condition", - "removeCondition": "Remove condition", - "valuePlaceholder": "Value", - "valueListPlaceholder": "Comma-separated values", - "incomplete": "Fill in the rule name, description, at least one tag and complete every condition." - }, - "view": { - "description": "Description", - "tags": "Tags", - "conditions": "Conditions", - "audit": "Audit", - "createdBy": "Created by", - "createdDate": "Created", - "modifiedBy": "Modified by", - "modifiedDate": "Modified" - }, - "toast": { - "created": "Rule \"{{name}}\" created.", - "updated": "Rule \"{{name}}\" updated.", - "deleted": "Rule \"{{name}}\" deleted.", - "createError": "Failed to create rule.", - "updateError": "Failed to update rule.", - "deleteError": "Failed to delete rule." - }, - "deleteTitle": "Delete tagging rule" - }, - "incidents": { - "title": "Incidents", - "subtitle": "Group, triage and resolve related alerts as incidents.", - "refresh": "Refresh", - "count_one": "{{count}} incident", - "count_other": "{{count}} incidents", - "openNow": "open now", - "empty": "No incidents match.", - "loadError": "Could not load incidents.", - "retry": "Retry", - "unassigned": "Unassigned", - "unknownUser": "Unknown", - "status": { - "open": "Open", - "in_review": "In review", - "completed": "Completed", - "merged": "Merged" - }, - "sev": { - "high": "High", - "medium": "Medium", - "low": "Low", - "unknown": "Unrated" - }, - "toolbar": { - "search": "Search incidents…", - "create": "Create incident", - "allSeverities": "All severities", - "export": "Export CSV" - }, - "statusTabs": { - "all": "All" - }, - "filters": { - "add": "Add filter", - "clearAll": "Clear all", - "filterValues": "Filter values…", - "loadingValues": "Loading values…", - "noValues": "No values found.", - "pickValue": "Pick a value to add the filter.", - "empty": "(empty)", - "cancel": "Cancel", - "addBtn": "Add" - }, - "ops": { - "IS": "is" - }, - "create": { - "title": "Create incident", - "stepIndicator": "Step {{current}} of {{total}}", - "selectedCount": "{{count}} alerts selected", - "submit": "Create", - "success": "Incident created", - "error": "Could not create the incident", - "details": { - "nameLabel": "Name", - "namePlaceholder": "Short, descriptive title", - "descriptionLabel": "Description", - "descriptionPlaceholder": "Context, scope, initial notes…" - } - }, - "layout": { - "table": "Table", - "board": "Board" - }, - "table": { - "name": "Incident", - "status": "Status", - "severity": "Severity", - "assignee": "Assignee", - "alerts": "Alerts", - "created": "Created" - }, - "drawer": { - "created": "Created {{date}}", - "alertsCount": "{{count}} alerts", - "solutionPlaceholder": "Resolution / remediation notes…", - "solutionHint": "Saved when you move the incident to Completed.", - "tabs": { - "overview": "Overview", - "alerts": "Alerts", - "notes": "Notes", - "history": "History" - }, - "section": { - "description": "Description", - "solution": "Solution", - "details": "Details" - }, - "details": { - "id": "ID", - "status": "Status", - "severity": "Severity", - "assignee": "Assignee", - "created": "Created", - "alerts": "Linked alerts" - } - }, - "alerts": { - "empty": "No alerts linked to this incident.", - "remove": "Unlink alert", - "removeConfirm": "Unlink “{{name}}” from this incident?", - "removed": "Alert unlinked", - "removeError": "Could not unlink the alert", - "loadingAlert": "Loading alert…", - "alertGone": "This alert is no longer in the store — retention may have dropped it.", - "alertFailed": "Could not load the alert.", - "openInAlerts": "Open in Alerts" - }, - "notes": { - "empty": "No notes yet.", - "add": "Add note", - "addError": "Could not add the note", - "placeholder": "Write a note…" - }, - "history": { - "empty": "No history yet." - }, - "toast": { - "statusChanged": "Incident status updated", - "statusError": "Could not change the status", - "exportFailed": "Failed to export CSV" - }, - "assign": { - "assign": "Assign", - "search": "Search users…", - "unassign": "Unassign", - "noUsers": "No users", - "assigned": "Assigned to {{user}}", - "unassigned": "Incident unassigned", - "error": "Could not change the assignee", - "custom": "Assign custom", - "customPlaceholder": "Type a login…" - }, - "action": { - "INCIDENT_CREATED": "Incident created", - "INCIDENT_ALERT_ADD": "Alerts added", - "INCIDENT_ALERT_STATUS_CHANGED": "Alert status changed", - "INCIDENT_STATUS_CHANGE": "Status changed", - "INCIDENT_NOTE_ADD": "Note added", - "INCIDENT_NOTE_CHANGE": "Note edited", - "INCIDENT_ASSIGNED": "Assignee changed" - } - }, - "parsingFilters": { - "title": "Pipelines", - "subtitle": "YAML pipelines applied to logs as they're parsed during ingestion.", - "new": "New pipeline", - "search": "Search pipelines…", - "refresh": "Refresh", - "view": "View", - "system": "System", - "user": "Custom", - "loading": "Loading pipelines…", - "loadError": "Could not load pipelines.", - "retry": "Retry", - "empty": "No pipelines match this view.", - "tabs": { - "all": "All", - "active": "Active", - "inactive": "Inactive", - "system": "System", - "user": "Custom" - }, - "cols": { - "filter": "Pipeline", - "type": "Type", - "active": "Active", - "dataTypes": "Data types", - "order": "Order", - "moveUp": "Move up", - "moveDown": "Move down", - "actions": "Actions" - }, - "editor": { - "titleNew": "New pipeline", - "titleEdit": "Edit pipeline", - "titleSystem": "Pipeline (system)", - "name": "Name", - "namePlaceholder": "My custom pipeline", - "nameHint": "Will be saved as {{file}}", - "namePending": "Pick a name — it will become the filename.", - "content": "Content (pipeline YAML)", - "contentHint": "A valid pipeline: YAML definition.", - "readOnly": "System pipeline — read-only. You can only enable or disable it.", - "test": "Test", - "save": "Save", - "saving": "Saving…", - "delete": "Delete", - "confirmDelete": "Confirm delete", - "cancel": "Cancel" - }, - "toast": { - "saved": "Pipeline saved", - "saveError": "Failed to save pipeline", - "deleted": "Pipeline deleted", - "deleteError": "Failed to delete pipeline", - "activateError": "Failed to change pipeline state", - "nameRequired": "Name is required", - "contentRequired": "Content is required", - "orderError": "Failed to reorder pipeline" - }, - "visual": { - "visualTab": "Visual", - "codeTab": "Code", - "codeOnly": "Switch to Code — this content can't be shown visually.", - "cantParse": "Can't open the visual editor: {{error}}", - "dataTypes": "Data types", - "steps": "Steps", - "noSteps": "No steps yet.", - "addStep": "Add step:", - "removeStep": "Remove step", - "moveUp": "Move up", - "moveDown": "Move down", - "whereHint": "optional condition (CEL)", - "addValue": "Add value", - "addPattern": "Add pattern", - "rawHint": "This processor is edited as raw YAML.", - "rawNotMap": "Must be a set of key: value fields.", - "dataTypesPick": "Choose data types", - "dataTypesSearch": "Search data types…", - "dataTypesNone": "No data types", - "dataTypesAdd": "Add \"{{value}}\"", - "insertPattern": "Insert regex pattern", - "patternSearch": "Search patterns…", - "patternNone": "No patterns", - "newPattern": "New pattern…", - "createInsert": "Create & insert", - "patternCreated": "Pattern \"{{name}}\" created", - "patternCreateError": "Failed to create pattern", - "patternIdInvalid": "Pattern ID must start with a letter or _ and use only letters, digits or _", - "patternDefRequired": "Definition is required", - "parameters": "Parameters", - "paramsKey": "Key", - "paramsValue": "Value", - "entry": "Entry {{n}}", - "order": "order {{n}}", - "orderLabel": "Order", - "removeEntry": "Remove entry", - "addEntry": "Add pipeline entry", - "collapse": "Collapse", - "expand": "Expand", - "splitHint": "Blank defaults to a single space — the YAML always shows it as fieldSplit: \" \"." - }, - "allDataTypes": "All data types", - "testPipeline": "Test pipeline" - }, - "playground": { - "titleFilter": "Test pipeline", - "titleRule": "Test rule", - "noDataTypes": "This pipeline has no data types assigned yet — add one to test it.", - "dataTypeLabel": "Data type", - "dataTypePlaceholder": "No data types available", - "dataTypeSingleHint": "This pipeline only has one data type — add more to choose between them.", - "rawLogLabel": "Raw log", - "rawLogPlaceholder": "Paste a sample raw log line…", - "rawLogCounter": "{{chars}} chars · {{kb}} KB", - "rawLogTooLarge": "This log exceeds the 1 MB limit — trim it before running the test.", - "run": { - "label": "Run", - "running": "Testing…", - "waitHint": "This can take up to 15 seconds while the pipeline processes the log." - }, - "errors": { - "busy": "The playground is busy running another test — please try again shortly.", - "timeout": "The test timed out — this usually means the selected data type doesn't match the log format.", - "validation": "The request was invalid — check the raw log and pipeline content.", - "server": "The playground couldn't complete the test — please try again." - }, - "notices": { - "geo": "The geolocation plugin isn't available in this lite version of the filter and rule test.", - "correlation": "Rules that reference prior events through afterEvent or correlation clauses require matching historical events to already exist in the system for the tested alert to trigger." - }, - "result": { - "label": "Parsed result", - "empty": "Run a test to see the parsed event here.", - "loading": "Waiting for the parsed event…", - "tabs": { - "fields": "Fields", - "json": "JSON" - }, - "fieldsCount_one": "{{count}} field", - "fieldsCount_other": "{{count}} fields", - "copy": "Copy", - "copied": "Copied", - "elapsed": "Parsed in {{time}}", - "elapsedHint": "Time from Run to the parsed result", - "searchPlaceholder": "Search fields…", - "noMatch": "No fields match your search." + "socAi": { + "title": "SOC-AI Configuration", + "subtitle": "Configure the AI agent that triages alerts and powers the operations assistant.", + "section": { + "connection": "Model & connection", + "auth": "Authentication", + "behavior": "Alert triage behavior", + "advanced": "Advanced" + }, + "usage": { + "title": "Usage", + "chat": "Chat completions (today)", + "unavailable": "Usage isn't available yet.", + "resetsIn": "Resets in {{time}}" + }, + "provider": { + "label": "Provider", + "hint": "Selects the wire format. Anything other than Anthropic uses the OpenAI-compatible API." + }, + "model": { + "label": "Model", + "hint": "Model identifier exposed by the provider.", + "customOption": "Custom model…", + "customPlaceholder": "Enter a model ID" + }, + "url": { + "label": "API URL", + "hint": "Leave empty to use the provider's default endpoint." + }, + "apiKey": { + "label": "API key", + "hint": "Credential sent to the provider.", + "setHint": "A key is stored. Leave blank to keep it." + }, + "authType": { + "label": "Authentication type", + "hint": "How credentials are sent to your gateway.", + "options": { + "apiKey": "API Key", + "bearer": "Bearer", + "customHeaders": "Custom Headers", + "none": "None" + } + }, + "authHeaderName": { + "label": "Auth header name", + "hint": "Header carrying the key (e.g. api-key for Azure)." + }, + "authToken": { + "label": "Bearer token", + "hint": "Credential sent to the provider.", + "setHint": "A token is stored. Leave blank to keep it." + }, + "customHeaders": { + "label": "Custom headers", + "hint": "Extra headers sent with every request. Values are encrypted; \"*****\" keeps the stored one.", + "keyPlaceholder": "Header name", + "valuePlaceholder": "Value", + "addRow": "Add header", + "remove": "Remove header" + }, + "maxTokens": { + "label": "Max tokens", + "hint": "Maximum tokens per LLM response." + }, + "maxToolIterations": { + "label": "Max tool iterations", + "hint": "Cap on the agent's plan -> tool -> observe loop." + }, + "autoAnalyze": { + "label": "Auto-analyze alerts", + "hint": "Triage incoming alerts in real time." + }, + "allowIncidents": { + "label": "Allow managing incidents", + "hint": "The triage agent may create or update incidents when it decides an alert warrants one." + }, + "changeAlertStatus": { + "label": "Change alert status", + "hint": "Let the agent set an alert's status during triage." + }, + "automaticIncidentCreation": { + "label": "Create incidents", + "hint": "Let the agent open incidents from triaged alerts." + }, + "allowedWriteTools": { + "label": "Allowed write tools", + "hint": "One MCP tool name per line the triage agent may use (e.g. alerts.update_status). Notes are always allowed." + }, + "save": "Save configuration", + "saving": "Verifying & saving...", + "saved": "SOC-AI configuration saved", + "saveError": "Failed to save configuration", + "loadError": "Failed to load configuration", + "modelRequired": "Model is required", + "applyTags": { + "label": "Apply tags", + "hint": "Let the agent tag alerts during triage." + }, + "note": { + "azure": "Paste your full Azure deployment endpoint as the URL; the model is your deployment name. Auth uses the api-key header.", + "ollama": "Point the URL at your Ollama host. No API key is needed for a local instance.", + "custom": "Any OpenAI-compatible endpoint. Set the URL, auth and any extra headers your gateway needs.", + "threatwinds": "Uses your UTMStack license automatically — no API key needed. Billed through your ThreatWinds subscription." + }, + "chat": { + "title": "SOC Assistant", + "dashboardCreateTitle": "Dashboard builder", + "empty": "Ask anything about your alerts, detections or the console — I can investigate and act on the SIEM.", + "tryPrefix": "Try", + "suggestion": "how many open alerts, grouped by adversary?", + "placeholder": "Ask a question…", + "ask": "Ask", + "send": "Send", + "collapse": "Collapse", + "expand": "Expand", + "clear": "Clear conversation", + "close": "Close", + "copy": "Copy", + "copied": "Copied", + "errorGeneric": "Something went wrong.", + "errorUnreachable": "Failed to reach the assistant.", + "compacting": "Compacting context…", + "dashboardEditTitle": "Dashboard editor", + "editingDashboard": "Editing: {{name}}", + "soarEditTitle": "SOAR flow editor", + "soarCreateTitle": "Create SOAR flow", + "editingFlow": "Editing flow: {{name}}" + }, + "focus": { + "alert": "Alert", + "incident": "Incident", + "remove": "Stop sharing with the assistant" + }, + "inheritance": { + "inherited": "Following the instance default. Saving here gives this tenant its own configuration.", + "own": "This tenant has its own configuration.", + "revert": "Follow the instance default", + "reverting": "Reverting…", + "reverted": "Now following the instance default" + }, + "allowance": { + "title": "AI allowance today", + "ofLimit": "of {{limit}} requests", + "denied": "requests — the AI is not available to this tenant", + "hint": "Set by whoever runs the instance. It resets at midnight UTC." + } }, "alerts": { - "label": "Alerts", - "empty": "Run a test to see any resulting alerts here.", - "none": "No alerts were triggered.", - "count_one": "{{count}} alert", - "count_other": "{{count}} alerts" - }, - "title": "Test pipeline" - }, - "alertingRules": { - "title": "Alerting Rules", - "subtitle": "Correlation rules that turn events into alerts. Toggle, tune or author your own.", - "new": "New rule", - "test": "Test", - "refresh": "Refresh", - "empty": "No rules match.", - "loadError": "Could not load the rules.", - "retry": "Retry", - "deleteConfirm": "Delete the rule “{{name}}”?", - "adversary": { - "origin": "Origin", - "target": "Target" - }, - "state": { - "active": "Active", - "inactive": "Inactive" - }, - "owner": { - "system": "System", - "custom": "Custom" - }, - "toolbar": { - "search": "Search rules…", - "allCategories": "All categories", - "allAdversaries": "All adversaries", - "allStates": "All states", - "allOwners": "All owners", - "allDataTypes": "All data types" - }, - "table": { - "name": "Rule", - "category": "Category", - "technique": "Technique", - "adversary": "Adversary", - "impact": "Impact", - "active": "Active", - "dataTypes": "Data types", - "selectAll": "Select all", - "selectRow": "Select {{name}}" - }, - "export": { - "all": "Export All", - "selected": "Export ({{count}})", - "error": "Could not export the rules" - }, - "view": { - "description": "Description", - "details": "Details", - "impact": "Impact (C·I·A)", - "dataTypes": "Data types", - "updated": "Updated", - "relPath": "Path", - "definition": "Condition (CEL)", - "correlationSteps": "Correlation steps", - "correlation": "Correlation", - "groupBy": "Group by", - "deduplicateBy": "Deduplicate by", - "references": "References" - }, - "editor": { - "createTitle": "New rule", - "edit": "Edit", - "delete": "Delete", - "export": "Export", - "cancel": "Cancel", - "save": "Save", - "test": "Test", - "metadata": "Metadata", - "name": "Name", - "confidentiality": "Confidentiality", - "integrity": "Integrity", - "availability": "Availability", - "dataTypes": "Data types", - "dataTypesHint": "comma-separated", - "activeOnSave": "Active", - "definitionSection": "Definition", - "where": "Condition (CEL)", - "whereHint": "CEL expression evaluated per event", - "correlationSteps": "Correlation steps", - "correlationStepsHint": "JSON array", - "jsonArray": "JSON array", - "nameRequired": "Name is required", - "definitionRequired": "The condition is required", - "invalidJson": "A definition field has invalid JSON", - "addStep": "Add correlation step", - "step": "Step {{n}}", - "removeStep": "Remove step", - "indexPattern": "Index pattern", - "within": "Within", - "count": "Count", - "conditions": "Conditions", - "field": "Field", - "value": "Value", - "addCondition": "Add condition", - "orGroup": "Or group {{n}}", - "addOr": "Add Or group", - "removeOr": "Remove", - "fieldsHint": "field names", - "referencesHint": "URLs", - "visual": "Visual", - "code": "Code", - "dataTypesPick": "Select…", - "dataTypesSearch": "Search data types…", - "dataTypesNone": "No data types", - "visualTab": "Visual", - "codeTab": "Code", - "yamlError": "Can't apply the YAML: {{error}}" - }, - "toast": { - "activated": "Rule activated", - "deactivated": "Rule deactivated", - "toggleError": "Could not change the rule state", - "deleted": "Rule deleted", - "deleteError": "Could not delete the rule", - "created": "Rule created", - "saved": "Rule saved", - "saveError": "Could not save the rule" - }, - "operator": { - "filter_term": "equals (term)", - "must_not_term": "not equals (term)", - "filter_match": "matches (text)", - "must_not_match": "not matches (text)" - }, - "where": { - "matchPrefix": "Match", - "all": "all", - "any": "any", - "matchSuffix": "of these conditions:", - "negate": "Negate", - "listHint": "comma-separated", - "advanced": "This condition uses advanced CEL — edit it in Code, or rebuild it visually.", - "and": "AND", - "or": "OR" - }, - "celOp": { - "exists": "exists", - "equals": "equals", - "equalsIgnoreCase": "equals (no case)", - "contains": "contains", - "oneOf": "is one of", - "containsAll": "contains all", - "startsWith": "starts with", - "endsWith": "ends with", - "regexMatch": "matches regex", - "lessThan": "<", - "lessOrEqual": "≤", - "greaterThan": ">", - "greaterOrEqual": "≥", - "inCIDR": "in CIDR", - "isHour": "hour is", - "isMinute": "minute is", - "isDayOfWeek": "day of week is", - "isWeekend": "is weekend", - "isWorkDay": "is workday", - "isBetweenTime": "time between" - }, - "import": { - "button": "Import", - "error": "Import failed", - "resultTitle": "Import results", - "approved": "Approved", - "rejected": "Rejected", - "done": "Done" - } - }, - "regexPatterns": { - "title": "Regex Patterns", - "subtitle": "Reusable regular expressions referenced by parsing filters.", - "new": "New pattern", - "search": "Search patterns…", - "refresh": "Refresh", - "view": "View", - "system": "System", - "user": "Custom", - "loading": "Loading patterns…", - "loadError": "Could not load patterns.", - "retry": "Retry", - "empty": "No patterns match this view.", - "tabs": { - "all": "All", - "system": "System", - "user": "Custom" - }, - "cols": { - "pattern": "Pattern", - "definition": "Definition", - "type": "Type" - }, - "editor": { - "titleNew": "New pattern", - "patternId": "Pattern ID", - "patternIdHint": "Unique name referenced from filters.", - "description": "Description", - "descriptionPlaceholder": "What this pattern matches (optional)", - "definition": "Definition (regex)", - "definitionHint": "A regular expression. Can reference other patterns.", - "readOnly": "System pattern — read-only.", - "save": "Save", - "saving": "Saving…", - "delete": "Delete", - "confirmDelete": "Confirm delete", - "cancel": "Cancel" - }, - "toast": { - "saved": "Pattern saved", - "saveError": "Failed to save pattern", - "deleted": "Pattern deleted", - "deleteError": "Failed to delete pattern", - "patternIdRequired": "Pattern ID is required", - "definitionRequired": "Definition is required" - } - }, - "soar": { - "title": "SOAR", - "subtitle": "Automated alert-response flows: conditions match an alert, commands run on the agent.", - "comingSoon": "Coming soon", - "console": { - "loading": "Loading agents…", - "loadError": "Could not load agents.", - "pickAgent": "Select an agent", - "pickAgentHint": "Choose an agent from the list to open its interactive console.", - "lockedAgent": "Remote control disabled" - }, - "search": "Search flows…", - "refresh": "Refresh", - "new": "New flow", - "view": "View", - "system": "System", - "loading": "Loading flows…", - "loadError": "Could not load flows.", - "retry": "Retry", - "empty": "No flows match this view.", - "templates": { - "title": "Start a new flow", - "subtitle": "Pick an action template or start from scratch.", - "loading": "Loading templates…", - "loadError": "Could not load templates.", - "empty": "No templates available.", - "cancel": "Cancel", - "scratch": "Start from scratch" - }, - "tabs": { - "flows": "Flows", - "executions": "Execution history", - "all": "All", - "active": "Active", - "inactive": "Inactive", - "system": "System", - "user": "Custom" - }, - "cols": { - "flow": "Flow", - "platform": "Platform", - "conditions": "Conditions", - "commands": "Commands", - "active": "Active", - "lastRun": "Last run", - "failedRuns_one": "{{count}} failed run", - "failedRuns_other": "{{count}} failed runs" - }, - "operator": { - "IS": "is", - "IS_NOT": "is not", - "CONTAINS": "contains", - "NOT_CONTAINS": "does not contain", - "EXISTS": "exists", - "NOT_EXISTS": "does not exist", - "START_WITH": "starts with", - "NOT_START_WITH": "does not start with", - "ENDS_WITH": "ends with", - "NOT_ENDS_WITH": "does not end with", - "IS_ONE_OF": "is one of", - "IS_NOT_ONE_OF": "is not one of" - }, - "toast": { - "created": "Flow created", - "saved": "Flow saved", - "saveError": "Failed to save flow", - "deleted": "Flow deleted", - "deleteError": "Failed to delete flow", - "activateError": "Failed to change flow state" - }, - "editor": { - "createTitle": "New flow", - "visualTab": "Visual", - "codeTab": "Code", - "name": "Name", - "description": "Description", - "conditions": "Conditions", - "conditionsHint": "The flow runs when an alert matches ALL of these conditions.", - "field": "field", - "value": "value", - "valueList": "comma-separated values", - "addCondition": "Add condition", - "commands": "Commands", - "commandsHint": "Run in order on the agent. Use $(field.path) for alert values and $[variables.NAME] for stored variables.", - "addCommand": "Add command", - "templatesButton": "Common commands", - "templates": { - "isolate": "Isolate from network", - "shutdown": "Shutdown machine", - "killProcess": "Kill process", - "logout": "Log out user", - "disableUser": "Disable user", - "blockIp": "Block IP", - "restart": "Restart machine", - "uninstall": "Uninstall application" - }, - "connector": { - "always": "always", - "success": "on success", - "failure": "on failure" - }, - "agentPlatform": "Agent platform", - "shell": "Shell", - "shellAuto": "auto", - "whereToRun": "Where to run", - "run": { - "all": "All agents", - "specific": "One agent", - "except": "All except", - "allHint": "Runs on every agent that matches this platform." - }, - "selectAgentPlaceholder": "Select an agent…", - "excludedAgentsHint": "type a hostname and press Enter", - "save": "Save", - "delete": "Delete", - "confirmDelete": "Confirm delete", - "cancel": "Cancel", - "yamlError": "Can't apply the YAML: {{error}}", - "nameRequired": "Name is required", - "conditionsRequired": "At least one condition with a field is required", - "commandsRequired": "At least one command is required", - "httpUrlInvalid": "HTTP node \"{{id}}\" has an invalid URL — must be a valid http(s) URL.", - "httpBodyInvalid": "HTTP node \"{{id}}\" body is not valid JSON: {{error}}", - "incidentNameRequired": "Incident node \"{{id}}\" needs a name.", - "mailToRequired": "Email node \"{{id}}\" needs at least one recipient.", - "mailAddressInvalid": "Email node \"{{id}}\" has an invalid {{field}} address: {{address}}.", - "mailSubjectRequired": "Email node \"{{id}}\" needs a subject.", - "identityModalTitle": "Flow details", - "platformRequired": "Agent platform is required", - "nameLabel": "Name", - "namePlaceholder": "Flow name", - "descriptionLabel": "Description", - "descriptionHint": "What does this flow do? (optional)", - "when": "When", - "whenTitle": "An alert matches all of these conditions", - "on": "On", - "onTitle": "The matching agent", - "thenRun": "Then run", - "thenTitle": "These commands, in order", - "selectField": "Select a field…", - "selectPlatform": "Select a platform…", - "searchAgents": "Search agents…", - "noAgents": "No agents", - "insertInto": "Insert into command {{n}}:", - "insertField": "Alert field", - "variables": "Variables", - "canvas": { - "node": "Node", - "deleteNode": "Delete node", - "id": "ID", - "kind": "Kind", - "executor": "Executor", - "commandLabel": "Command", - "paramsJson": "Params (JSON)", - "dragToResize": "Drag to resize", - "templatesLabel": "Templates", - "templatesNeedPlatform": "First select target platform", - "handlesHint": "Drag from the bottom-left green handle for on_success, the bottom-right red handle for on_error. Multiple wires = parallel. Multiple wires into one node = AND-join.", - "invalidJson": "invalid JSON", - "hidePalette": "Hide palette", - "hideInspector": "Hide inspector", - "paletteLabel": "Palette", - "nodeShort": "Node", - "showPanel": "Show {{name}}", - "platform": "Platform", - "shell": "Shell", - "any": "any", - "auto": "auto", - "runOn": "Run on", - "runAutoTitle": "Runs on the host that raised the alert", - "runSpecificTitle": "Pin to one host (or a template like $(alert.foo))", - "runExceptTitle": "Runs on the host that raised the alert, but skips ones in the list", - "runAutoLabel": "alert source", - "runSpecificLabel": "one host", - "runExceptLabel": "all except", - "runAutoHint": "Runs on $(alert.dataSource) — the host that raised the matched alert.", - "pickHost": "pick a host…", - "orTemplateHint": "Or type a template — $(alert.field) resolves per execution.", - "addExclusion": "add exclusion", - "searchAgents": "search agents…", - "noAgents": "no agents", - "insertField": "Insert field", - "alert": "Alert", - "wholeOutput": "whole output (edit the path)", - "noAncestorsHint": "No enrichment ancestors yet — add an enrichment node upstream to expose its output here.", - "inserts": "inserts", - "conditionalHint": "All conditions must match. Match → success branch (green); miss → error branch (red).", - "http": { - "url": "URL", - "urlInvalid": "Not a valid http(s) URL.", - "method": "Method", - "body": "Body (JSON)", - "bodyInvalid": "Invalid JSON", - "headers": "HTTP headers", - "params": "Query params", - "key": "Key", - "value": "Value", - "addHeader": "Add header", - "addParam": "Add param" + "title": "Alerts", + "matching": "{{count}} matching", + "subtitle": "Triage what matters.", + "openNow": "open right now.", + "view": { + "alerts": "Alerts", + "overview": "Overview" + }, + "toolbar": { + "searchPlaceholder": "Search by alert name…", + "allSeverities": "All severities", + "export": "Export CSV", + "refresh": "Refresh" + }, + "severity": { + "high": "High", + "medium": "Medium", + "low": "Low" + }, + "status": { + "open": "Open", + "in_review": "In review", + "completed": "Completed", + "auto": "Automatic review" + }, + "statusTabs": { + "all": "All" + }, + "overview": { + "overTime": "Alerts over time", + "matchingAlerts": "matching alerts", + "noData": "No data.", + "bySeverity": "By severity", + "byStatus": "By status" + }, + "filters": { + "add": "Add filter", + "clearAll": "Clear all", + "filterValues": "Filter values…", + "loadingValues": "Loading values…", + "noValues": "No values found.", + "pickValue": "Pick a value to add the filter.", + "empty": "(empty)", + "cancel": "Cancel", + "addBtn": "Add" + }, + "ops": { + "CONTAIN": "contains", + "IS": "is", + "IS_NOT": "is not", + "EXIST": "exists", + "DOES_NOT_EXIST": "does not exist" + }, + "fields": { + "adversary_domain": "Adversary domain", + "adversary_geolocation_asn": "Adversary ASN", + "adversary_geolocation_aso": "Adversary ASO", + "adversary_geolocation_country": "Adversary country", + "adversary_host": "Adversary host", + "adversary_ip": "Adversary IP", + "adversary_url": "Adversary URL", + "adversary_user": "Adversary user", + "assignee": "Assignee", + "category": "Category", + "dataSource": "Sensor", + "dataType": "Data type", + "description": "Description", + "id": "ID", + "impactScore": "Risk", + "impact_availability": "Availability", + "impact_confidentiality": "Confidentiality", + "impact_integrity": "Integrity", + "incidentDetail_incidentName": "Incident name", + "incidentDetail_incidentId": "Incident id", + "isIncident": "Is incident", + "name": "Alert name", + "notes": "Notes", + "severity": "Severity", + "status": "Status", + "tags": "Tags", + "target_domain": "Target domain", + "target_geolocation_asn": "Target ASN", + "target_geolocation_aso": "Target ASO", + "target_geolocation_country": "Target country", + "target_host": "Target host", + "target_ip": "Target IP", + "target_url": "Target URL", + "target_user": "Target user", + "technique": "Technique" + }, + "tagFilter": { + "tags": "Tags", + "tag_one": "{{count}} tag", + "tag_other": "{{count}} tags", + "clearSelection": "Clear selection", + "noTags": "No tags" + }, + "bulk": { + "selected": "{{count}} selected", + "setStatus": "Set status", + "addTag": "Add tag", + "noTags": "No tags", + "addToIncident": "Add to incident", + "clear": "Clear" + }, + "tagEditor": { + "tag": "Tag", + "noTagsYet": "No tags yet", + "createTag": "Create tag", + "newTagName": "New tag name…", + "createApply": "Create and apply tag", + "save": "Save", + "cancel": "Cancel", + "edit": "Edit tag", + "delete": "Delete tag", + "createRule": "Create tagging rule with this tag", + "systemLocked": "System tag (locked)", + "alreadyExists": "That tag already exists.", + "color": "Color {{color}}" + }, + "table": { + "actions": "Actions", + "alert": "Alert", + "status": "Status", + "technique": "Technique", + "severity": "Severity", + "risk": "Risk", + "echoes": "Echoes", + "time": "Time", + "riskHint": "Risk score (0–100), colored by severity", + "source": "Source", + "adversary": "Adversary" + }, + "row": { + "createRuleFromAlert": "Create a tag from this alert", + "createIncident": "Create incident from this alert", + "viewIncident": "View incident details", + "assignedTo": "Assigned to {{user}}", + "echoesTooltip": "{{count}} echoes — click to expand", + "echoesEmpty": "No echoes recorded" + }, + "echoes": { + "title": "{{count}} echoes", + "close": "Close", + "empty": "No echoes recorded for this alert.", + "loadError": "Could not load echoes." + }, + "list": { + "loading": "Loading alerts…", + "loadError": "Could not load alerts.", + "retry": "Retry", + "empty": "No alerts match this view." + }, + "badge": { + "incident": "Incident", + "aiAssessed": "AI assessed" + }, + "drawer": { + "setStatus": "Set status", + "completeFalsePositive": "Complete + false positive", + "addToIncident": "Add to incident", + "partOfIncident": "Part of an incident", + "tabs": { + "summary": "Summary", + "parties": "Parties", + "events": "Events", + "history": "History" + }, + "section": { + "description": "Description", + "solution": "Solution", + "references": "References", + "details": "Details", + "yourNotes": "Your notes", + "notes": "Notes" + }, + "details": { + "severity": "Severity", + "risk": "Risk", + "category": "Category", + "technique": "Technique", + "sensor": "Sensor", + "dataType": "Data type", + "alertId": "Alert ID", + "statusNote": "Status note", + "assignee": "Assignee" + }, + "incidentDetail": { + "incident": "Incident", + "id": "ID", + "createdBy": "Created by", + "created": "Created" + }, + "notesPlaceholder": "Add investigation notes…", + "saveNotes": "Save notes", + "assignee": "Assign", + "assign": "Assign", + "unassign": "Unassign", + "unassigned": "Unassigned", + "loadingUsers": "Loading users…", + "observationLabel": "Observation", + "observationPlaceholder": "Add an observation…", + "cancel": "Cancel", + "continue": "Continue" + }, + "related": { + "sample": "A sample of up to ~11 events the engine stored on this alert. Use “View all related logs” for the full, uncapped set.", + "loadingEchoes": "Loading the events of its echoes…", + "sampleWithEchoes": "The events stored on this alert and on its {{count}} echoes ({{read}} read). Use “View all related logs” for the full, uncapped set.", + "empty": "No sampled events stored on this alert. Load the full correlated set in the Log Explorer.", + "viewAll": "View all related logs" + }, + "party": { + "source": "Source / target", + "adversary": "Adversary", + "noData": "No data.", + "ip": "IP", + "host": "Host", + "user": "User", + "domain": "Domain", + "country": "Country" + }, + "history": { + "empty": "No history recorded.", + "by": "by {{user}}", + "actions": { + "UPDATE_STATUS": "Status updated", + "UPDATE_TAGS": "Tags updated", + "UPDATE_NOTES": "Notes updated", + "UPDATE_SOLUTION": "Solution updated", + "MARK_AS_INCIDENT": "Marked as incident" + }, + "detail": { + "statusTo": "Status → {{status}}", + "tags": "Tags: {{tags}}", + "aiAdded": "AI assessment added", + "observationAdded": "Observation added", + "notesUpdated": "Notes updated" + } + }, + "ai": { + "title": "SOC AI assessment", + "risk": "{{risk}} risk", + "score": "{{score}}/100", + "generate": "Generate AI summary", + "hint": "SOC-AI investigates this alert and adds an assessment.", + "generating": "Analyzing the alert… this can take a minute.", + "ready": "AI summary ready", + "failed": "Could not generate the AI summary", + "slow": "The AI summary is taking longer than expected. It will show up on the alert when it is ready." }, "incident": { - "name": "Incident name", - "namePlaceholder": "e.g. Suspicious login on $(alert.dataSource)", - "description": "Description", - "descriptionPlaceholder": "Optional context for responders. Templates like $(alert.name) are interpolated." - }, - "llm": { - "prompt": "Prompt", - "hint": "The model is instructed to always answer with a single JSON object carrying a \"result\" property. The backend guarantees this shape even if the model deviates. Child nodes reference it via $({{nodeId}}.result) or specific fields." - }, - "mail": { - "to": "To (comma-separated)", - "cc": "CC (comma-separated, optional)", - "addressInvalid": "Invalid email address: {{address}}", - "subject": "Subject", - "subjectPlaceholder": "e.g. Alert on $(alert.dataSource)", - "body": "Body", - "bodyPlaceholder": "Message body. Templates like $(alert.name) are interpolated." - }, - "notify": { - "level": "Level", - "message": "Message", - "messagePlaceholder": "Notification text. Templates like $(alert.name) are interpolated." + "titleAdd_one": "Add {{count}} alert to an incident", + "titleAdd_other": "Add {{count}} alerts to an incident", + "new": "New incident", + "existing": "Existing incident", + "nameLabel": "Incident name", + "namePlaceholder": "e.g. Suspected Scattered Spider intrusion", + "descriptionLabel": "Description", + "descriptionPlaceholder": "Optional summary…", + "pickLabel": "Pick an incident", + "loading": "Loading…", + "selectPlaceholder": "Select an incident…", + "willLink_one": "{{count}} alert will be linked.", + "willLink_other": "{{count}} alerts will be linked.", + "cancel": "Cancel", + "create": "Create incident", + "add": "Add to incident" + }, + "toast": { + "statusUpdated": "Status updated", + "statusFailed": "Failed to update status", + "tagsUpdated": "Tags updated", + "tagsFailed": "Failed to update tags", + "tagCreateFailed": "Failed to create tag", + "tagUpdated": "Tag updated", + "tagUpdateFailed": "Failed to update tag", + "tagDeleted": "Tag deleted", + "tagDeleteFailed": "Failed to delete tag", + "notesSaved": "Notes saved", + "notesFailed": "Failed to save notes", + "exportFailed": "Failed to export CSV", + "noRelatedLogs": "No related logs found for this alert", + "relatedLogsFailed": "Failed to load related logs", + "incidentCreated": "Incident created", + "alertsAdded": "Alerts added to incident", + "incidentFailed": "Failed to save incident", + "assigned": "Alert assigned", + "unassigned": "Alert unassigned", + "assignFailed": "Could not update assignee", + "newAlertsToast_title": "New alerts", + "newAlertsToast_count_one": "{{count}} new alert", + "newAlertsToast_count_other": "{{count}} new alerts", + "newAlertsToast_view": "View" } - } - }, - "executions": { - "search": "Search by alert ID…", - "all": "All", - "loading": "Loading executions…", - "loadError": "Could not load executions.", - "retry": "Retry", - "empty": "No executions yet.", - "cols": { - "status": "Status", - "flow": "Flow", - "command": "Command / Action", - "agent": "Agent", - "date": "Date", - "retries": "Retries", - "node": "Node" - }, - "filters": { - "source": "Source", - "allSources": "All sources" - }, - "manual": "Interactive console" - }, - "executionStatus": { - "WAITING": "Waiting", - "PENDING": "Pending", - "EXECUTING": "Executing", - "EXECUTED": "Executed", - "FAILED": "Failed", - "DEAD": "Unreachable" - }, - "executionOrigin": { - "FLOW": "Flow", - "MANUAL": "Manual" - }, - "nonExecutionCause": { - "AGENT_OFFLINE": "Agent offline", - "AGENT_NOT_FOUND": "Agent not found", - "UNKNOWN": "Unknown" - }, - "kpi": { - "flows": "Total flows", - "active": "Active", - "runs24h": "Executions (24h)", - "failed24h": "Failed (24h)" - }, - "neverRun": "never", - "create": { - "title": "New flow", - "modeManual": "Create manually", - "modeAi": "Using AI", - "aiLocked": "Enable SOC-AI and configure it to use this.", - "name": "Flow name", - "namePlaceholder": "e.g. Block IP on repeated failures", - "aiDescriptionLabel": "What should this flow do?", - "aiDescriptionPlaceholder": "e.g. On a critical alert, look up the source IP in threat intel and block it on the firewall", - "aiCreate": "Create with AI", - "manualContinue": "Continue" - } - }, - "compliance": { - "title": "Compliance", - "subtitle": "Evaluate your posture against security frameworks — see which controls are met and which aren't.", - "comingSoon": "Coming soon.", - "tabs": { - "frameworks": "Frameworks", - "schedule": "Schedule", - "controls": "Controls" - }, - "search": "Search frameworks…", - "refresh": "Refresh", - "loading": "Loading frameworks…", - "loadError": "Could not load reports", - "retry": "Retry", - "empty": "No frameworks match.", - "notEvaluated": "Not evaluated", - "controlsCount": "{{n}} controls", - "enabledLabel": "Enabled", - "runReport": "Run report", - "backToFrameworks": "Back to frameworks", - "statusAuto": "Auto (evaluated)", - "overrideError": "Failed to update status", - "noteError": "Could not save the note", - "notes": { - "title": "Notes", - "placeholder": "Add a note…", - "save": "Save", - "cancel": "Cancel" - }, - "reasonModal": { - "title": "Reason required", - "description": "Provide a reason for this status change. It will be recorded.", - "label": "Reason", - "placeholder": "Explain why you are changing this control's status…", - "confirm": "Confirm change", - "cancel": "Cancel" - }, - "coverageLabel": "Coverage", - "activityLabel": "Activity", - "evidenceLabel": "Evidence", - "seeMore": "See more", - "seeLess": "See less", - "evaluating": "Evaluating framework…", - "complianceScore": "Compliance score", - "generatedAt": "Generated {{date}}", - "reportError": "Could not generate the report.", - "coverage": "{{n}} rules", - "activity": "{{n}} alerts", - "status": { - "COMPLIANT": "Compliant", - "NON_COMPLIANT": "Non-compliant", - "AT_RISK": "At risk", - "NOT_COVERED": "Not covered", - "OUT_OF_SCOPE": "Out of scope", - "PENDING": "Pending", - "label": "Status", - "NOT_EVALUATED": "Not evaluated" - }, - "toast": { - "toggleError": "Failed to change framework state", - "reportGenerated": "Report generated", - "reportError": "Failed to generate report" - }, - "schedule": { - "new": "New schedule", - "loading": "Loading schedules…", - "loadError": "Could not load schedules.", - "empty": "No schedules yet.", - "edit": "Edit", - "delete": "Delete", - "newTitle": "New schedule", - "editTitle": "Edit schedule", - "framework": "Framework", - "cadenceLabel": "Cadence", - "cronHint": "5-field cron (min hour day month weekday).", - "recipientsHint": "Comma-separated emails. Leave empty to only store the snapshot.", - "save": "Save", - "cancel": "Cancel", - "frameworkRequired": "Framework is required", - "cronRequired": "Schedule (cron) is required", - "cadence": { - "daily": "Daily", - "weekly": "Weekly", - "monthly": "Monthly", - "custom": "Custom" - }, - "toast": { - "saved": "Schedule saved", - "saveError": "Failed to save schedule", - "deleted": "Schedule deleted", - "deleteError": "Failed to delete schedule" - }, - "to": "To", - "cc": "Cc", - "toRequired": "At least one recipient is required", - "windowDays": "Reporting window (days)", - "windowDaysShort": "over {{days}}d", - "windowDaysHint": "How far back the report counts. Independent of how often it runs." - }, - "frameworks": { - "new": "New framework", - "edit": "Edit", - "createTitle": "New framework", - "visualTab": "Visual", - "codeTab": "Code", - "key": "Key", - "name": "Name", - "description": "Description", - "source": "Source", - "sections": "Sections", - "sectionKey": "section key", - "sectionName": "Section name", - "requirements": "Requirements", - "reqId": "req id", - "reqName": "Requirement name", - "addSection": "Add section", - "addRequirement": "Add requirement", - "satisfiedBy": "satisfied by controls", - "searchControls": "Search controls…", - "noControls": "No controls", - "save": "Save", - "delete": "Delete", - "confirmDelete": "Confirm delete", - "cancel": "Cancel", - "yamlError": "Can't apply the YAML: {{error}}", - "keyRequired": "Key is required", - "nameRequired": "Name is required", - "toast": { - "created": "Framework created", - "saved": "Framework saved", - "saveError": "Failed to save framework", - "deleted": "Framework deleted", - "deleteError": "Failed to delete framework" - }, - "createControl": "Create new control…", - "createNamed": "Create control \"{{name}}\"…" - }, - "controls": { - "search": "Search controls…", - "allFamilies": "All families", - "new": "New control", - "loading": "Loading controls…", - "loadError": "Could not load controls.", - "empty": "No controls match.", - "showingOf": "Showing {{shown}} of {{total}}", - "id": "ID", - "name": "Name", - "family": "Family", - "familyName": "Family", - "scope": "Scope", - "source": "Source", - "notInLibrary": "Control not found in library", - "scopeOpt": { - "data": "Data", - "governance": "Governance" - }, - "strategy": "Strategy", - "statement": "Statement", - "remediation": "Remediation", - "checks": "Checks", - "checksHint": "Each check runs an OpenSearch SQL query and applies a rule to decide pass/fail.", - "checkKey": "key", - "checkName": "Check name", - "rule": { - "MIN_HITS_REQUIRED": "Min hits required", - "THRESHOLD_MAX": "Threshold max" - }, - "ruleNone": "No rule", - "ruleValue": "value", - "addCheck": "Add check", - "createTitle": "New control", - "visualTab": "Visual", - "codeTab": "Code", - "save": "Save", - "delete": "Delete", - "confirmDelete": "Confirm delete", - "cancel": "Cancel", - "yamlError": "Can't apply the YAML: {{error}}", - "idRequired": "ID is required", - "nameRequired": "Name is required", - "anyDataType": "Any data type", - "addFilter": "Add filter", - "filterField": "log.eventCode", - "filterValue": "value", - "filterValues": "a, b, c", - "toast": { - "created": "Control created", - "saved": "Control saved", - "saveError": "Failed to save control", - "deleted": "Control deleted", - "deleteError": "Failed to delete control" - } - }, - "doc": { - "title": "Compliance Report", - "print": "Print / PDF", - "controlsEvaluated": "{{n}} controls evaluated", - "executiveSummary": "Executive Summary", - "bySection": "Findings by Section", - "footer": "{{framework}} — Compliance report generated {{date}} · {{brand}}", - "download": "Download PDF", - "downloadError": "Failed to download the PDF", - "error": "Could not generate the PDF", - "building": "Building the document…" - }, - "locked": { - "badge": "Enterprise", - "upgrade": "Upgrade to Enterprise", - "upsell": "This framework/control requires the Enterprise edition." - }, - "run": "Run evaluation", - "runError": "Evaluation failed", - "noReportYet": "This framework has not been evaluated yet.", - "window": "window {{from}} → {{to}}", - "scoredOver": "{{compliant}} of {{evaluated}} requirements met · {{total}} in the framework", - "editStale": "Recorded when the engine said {{was}}; it now says {{now}}", - "checkResults": "Check results", - "verdict": "Recorded verdict", - "engineSaid": "engine said", - "hits": "hits", - "noDataFor": "no {{dataType}} data in the window", - "setStatus": "Set status", - "outcome": { - "PASSED": "Passed", - "FAILED": "Failed", - "NOT_APPLICABLE": "No data", - "ERROR": "Error" - }, - "system": "Shipped", - "addNote": "Add a note", - "noteModal": { - "title": "Note", - "description": "Recorded on the report. It does not change the control’s status.", - "placeholder": "Remediation in progress — ticket OPS-4412, due end of quarter." - }, - "history": { - "title": "Score over time", - "score": "Compliance score", - "coverage": "Evaluated", - "error": "Could not load the score history" - } - }, - "tenants": { - "title": "Tenants", - "new": "New tenant", - "subtitle": "Every customer running on this instance, what they hold and what they let you see.", - "searchPlaceholder": "Search by name or domain…", - "loading": "Loading tenants…", - "loadFailed": "Could not load tenants.", - "retry": "Retry", - "none": "No tenants yet.", - "noSearchMatch": "No tenants match your search.", - "cancel": "Cancel", - "saving": "Saving…", - "chips": { - "total": "tenants", - "active": "active", - "readable": "readable" - }, - "status": { - "ACTIVE": "Active", - "SUSPENDED": "Suspended", - "TERMINATED": "Terminated" - }, - "support": { - "NONE": "No access", - "READ": "Read access", - "FULL": "Full access", - "hint": "Granted by the tenant, not by you. Only their administrator can change it." }, - "card": { - "edit": "Edit", - "activate": "Activate", - "deactivate": "Deactivate", - "deletePermanent": "Delete permanently", - "noAccess": "This tenant has not granted you access.", - "loadingStats": "Reading…", - "enter": "Enter" - }, - "stats": { - "users": "Users", - "datasources": "Sources", - "openAlerts": "Open alerts", - "ai": "AI today", - "noLimit": "no cap" - }, - "fields": { - "name": "Name", - "domain": "Domain", - "domainHint": "How this tenant is reached. Every request on this host lands in their data.", - "adminEmail": "Administrator email", - "adminEmailHint": "They get an invitation to set their own password.", - "status": "Status", - "suspendedWarning": "Suspended tenants cannot sign in. Their data is kept.", - "aiLimit": "AI request cap", - "aiLimitHint": "An operational cap, per day. Uncapped, they spend against the instance licence.", - "aiLimitToggle": "Cap this tenant" - }, - "create": { - "title": "New tenant", - "subtitle": "Creates the tenant and invites its first administrator.", - "submit": "Create tenant" - }, - "edit": { - "title": "Edit tenant", - "subtitle": "Support access is not here: only the tenant can grant it.", - "submit": "Save changes" - }, - "terminate": { - "title": "Deactivate this tenant?", - "body": "Nobody in {{name}} will be able to sign in. Their data is kept, so this is reversible, but it takes the customer offline now.", - "confirmLabel": "Type {{name}} to confirm", - "submit": "Deactivate" - }, - "reactivate": { - "title": "Activate this tenant?", - "body": "{{name}} will be able to sign in again. Their preserved data is restored as-is.", - "submit": "Activate" - }, - "deletePermanent": { - "title": "Delete this tenant forever?", - "body": "Every trace of {{name}} — users, data sources, dashboards, alerts, integrations — will be erased. This cannot be undone.", - "confirmLabel": "Type {{name}} to confirm", - "submit": "Delete forever" - }, - "toast": { - "created": "Tenant created", - "updated": "Tenant updated", - "terminated": "Tenant terminated", - "reactivated": "Tenant reactivated", - "permanentlyDeleted": "Tenant permanently deleted", - "domainInUse": "That domain is already taken", - "noPermission": "You do not have permission to do that", - "notFound": "Tenant not found", - "invalidRequest": "Invalid request", - "operationFailed": "Operation failed" - }, - "switcher": { - "aria": "Switch tenant", - "self": "Default tenant", - "create": "Create tenant" - } - }, - "supportAccess": { - "title": "Support access", - "intro": "Whoever operates this instance cannot look inside your data unless you let them. Nothing here is granted by default, and you can take it back at any time.", - "loading": "Loading…", - "loadFailed": "Could not read the current setting.", - "retry": "Retry", - "currentBadge": "current", - "save": "Save", - "saving": "Saving…", - "levels": { - "NONE": { - "name": "No access", - "desc": "The operator sees that your tenant exists and nothing else. Requests into your data are refused." - }, - "READ": { - "name": "Read only", - "desc": "The operator can look at your alerts, logs and configuration to help you. They cannot change anything — every write is refused, whatever their own role says." - }, - "FULL": { - "name": "Full access", - "desc": "The operator can act inside your tenant as an administrator: change configuration, users and response flows." - } + "taggingRules": { + "title": "Tagging Rules", + "subtitle": "Automatically tag alerts that match conditions.", + "new": "New rule", + "refresh": "Refresh", + "empty": "No tagging rules yet.", + "loadError": "Could not load tagging rules.", + "retry": "Retry", + "deleteConfirm": "Delete the rule \"{{name}}\"? Future alerts matching its conditions will stop being tagged.", + "toolbar": { + "search": "Search by rule name…", + "allTags": "All tags" + }, + "table": { + "rule": "Rule", + "tags": "Tags", + "conditions": "Conditions", + "modifiedBy": "Modified by", + "modifiedDate": "Modified" + }, + "drawer": { + "createTitle": "New tagging rule", + "edit": "Edit", + "delete": "Delete", + "save": "Save", + "create": "Create", + "cancel": "Cancel" + }, + "form": { + "basics": "Basics", + "name": "Rule name", + "namePlaceholder": "e.g. Internal SSH brute-force", + "description": "Description", + "descriptionPlaceholder": "Why this rule exists and what it tags.", + "tags": "Tags to apply", + "noTags": "No tags selected.", + "addTag": "Add tag", + "removeTag": "Remove", + "noCatalog": "No tags in the catalog yet.", + "createTag": "Create tag", + "newTagName": "New tag name", + "conditions": "Conditions (ALL must match)", + "noConditions": "At least one condition is required.", + "addCondition": "Add condition", + "removeCondition": "Remove condition", + "valuePlaceholder": "Value", + "valueListPlaceholder": "Comma-separated values", + "incomplete": "Fill in the rule name, description, at least one tag and complete every condition." + }, + "view": { + "description": "Description", + "tags": "Tags", + "conditions": "Conditions", + "audit": "Audit", + "createdBy": "Created by", + "createdDate": "Created", + "modifiedBy": "Modified by", + "modifiedDate": "Modified" + }, + "toast": { + "created": "Rule \"{{name}}\" created.", + "updated": "Rule \"{{name}}\" updated.", + "deleted": "Rule \"{{name}}\" deleted.", + "createError": "Failed to create rule.", + "updateError": "Failed to update rule.", + "deleteError": "Failed to delete rule." + }, + "deleteTitle": "Delete tagging rule" + }, + "incidents": { + "title": "Incidents", + "subtitle": "Group, triage and resolve related alerts as incidents.", + "refresh": "Refresh", + "count_one": "{{count}} incident", + "count_other": "{{count}} incidents", + "openNow": "open now", + "empty": "No incidents match.", + "loadError": "Could not load incidents.", + "retry": "Retry", + "unassigned": "Unassigned", + "unknownUser": "Unknown", + "status": { + "open": "Open", + "in_review": "In review", + "completed": "Completed", + "merged": "Merged" + }, + "sev": { + "high": "High", + "medium": "Medium", + "low": "Low", + "unknown": "Unrated" + }, + "toolbar": { + "search": "Search incidents…", + "create": "Create incident", + "allSeverities": "All severities", + "export": "Export CSV" + }, + "statusTabs": { + "all": "All" + }, + "filters": { + "add": "Add filter", + "clearAll": "Clear all", + "filterValues": "Filter values…", + "loadingValues": "Loading values…", + "noValues": "No values found.", + "pickValue": "Pick a value to add the filter.", + "empty": "(empty)", + "cancel": "Cancel", + "addBtn": "Add" + }, + "ops": { + "IS": "is" + }, + "create": { + "title": "Create incident", + "stepIndicator": "Step {{current}} of {{total}}", + "selectedCount": "{{count}} alerts selected", + "submit": "Create", + "success": "Incident created", + "error": "Could not create the incident", + "details": { + "nameLabel": "Name", + "namePlaceholder": "Short, descriptive title", + "descriptionLabel": "Description", + "descriptionPlaceholder": "Context, scope, initial notes…" + } + }, + "layout": { + "table": "Table", + "board": "Board" + }, + "table": { + "name": "Incident", + "status": "Status", + "severity": "Severity", + "assignee": "Assignee", + "alerts": "Alerts", + "created": "Created" + }, + "drawer": { + "created": "Created {{date}}", + "alertsCount": "{{count}} alerts", + "solutionPlaceholder": "Resolution / remediation notes…", + "solutionHint": "Saved when you move the incident to Completed.", + "tabs": { + "overview": "Overview", + "alerts": "Alerts", + "notes": "Notes", + "history": "History" + }, + "section": { + "description": "Description", + "solution": "Solution", + "details": "Details" + }, + "details": { + "id": "ID", + "status": "Status", + "severity": "Severity", + "assignee": "Assignee", + "created": "Created", + "alerts": "Linked alerts" + } + }, + "alerts": { + "empty": "No alerts linked to this incident.", + "remove": "Unlink alert", + "removeConfirm": "Unlink “{{name}}” from this incident?", + "removed": "Alert unlinked", + "removeError": "Could not unlink the alert", + "loadingAlert": "Loading alert…", + "alertGone": "This alert is no longer in the store — retention may have dropped it.", + "alertFailed": "Could not load the alert.", + "openInAlerts": "Open in Alerts" + }, + "notes": { + "empty": "No notes yet.", + "add": "Add note", + "addError": "Could not add the note", + "placeholder": "Write a note…" + }, + "history": { + "empty": "No history yet." + }, + "toast": { + "statusChanged": "Incident status updated", + "statusError": "Could not change the status", + "exportFailed": "Failed to export CSV" + }, + "assign": { + "assign": "Assign", + "search": "Search users…", + "unassign": "Unassign", + "noUsers": "No users", + "assigned": "Assigned to {{user}}", + "unassigned": "Incident unassigned", + "error": "Could not change the assignee", + "custom": "Assign custom", + "customPlaceholder": "Type a login…" + }, + "action": { + "INCIDENT_CREATED": "Incident created", + "INCIDENT_ALERT_ADD": "Alerts added", + "INCIDENT_ALERT_STATUS_CHANGED": "Alert status changed", + "INCIDENT_STATUS_CHANGE": "Status changed", + "INCIDENT_NOTE_ADD": "Note added", + "INCIDENT_NOTE_CHANGE": "Note edited", + "INCIDENT_ASSIGNED": "Assignee changed" + } }, - "fullWarning": "Full access lets the operator change things on your behalf. Grant it while you need hands-on help, and drop back afterwards.", - "revokeNote": "Everything the operator does here is recorded in your audit log.", - "toast": { - "granted": "Support access updated", - "revoked": "Support access revoked", - "forbidden": "Only an administrator of this tenant can change this", - "invalid": "Invalid request", - "failed": "Could not save the change" - } - }, - "supportSession": { - "inside": "You are working inside {{name}}", - "readOnly": "read only — writes are refused", - "full": "full access — changes here are real", - "leave": "Leave" - }, - "platformBroadcast": { - "button": "Apply to all tenants", - "action": { - "create": "Broadcast {{resource}} create", - "update": "Broadcast {{resource}} update", - "delete": "Broadcast {{resource}} delete", - "toggle": "Broadcast {{resource}} toggle", - "enable": "Broadcast {{resource}} enable", - "activate": "Broadcast {{resource}} activate", - "test": "Broadcast {{resource}} test", - "upload": "Broadcast {{resource}} asset" + "parsingFilters": { + "title": "Pipelines", + "subtitle": "YAML pipelines applied to logs as they're parsed during ingestion.", + "new": "New pipeline", + "search": "Search pipelines…", + "refresh": "Refresh", + "view": "View", + "system": "System", + "user": "Custom", + "loading": "Loading pipelines…", + "loadError": "Could not load pipelines.", + "retry": "Retry", + "empty": "No pipelines match this view.", + "tabs": { + "all": "All", + "active": "Active", + "inactive": "Inactive", + "system": "System", + "user": "Custom" + }, + "cols": { + "filter": "Pipeline", + "type": "Type", + "active": "Active", + "dataTypes": "Data types", + "order": "Order", + "moveUp": "Move up", + "moveDown": "Move down", + "actions": "Actions" + }, + "editor": { + "titleNew": "New pipeline", + "titleEdit": "Edit pipeline", + "titleSystem": "Pipeline (system)", + "name": "Name", + "namePlaceholder": "My custom pipeline", + "nameHint": "Will be saved as {{file}}", + "namePending": "Pick a name — it will become the filename.", + "content": "Content (pipeline YAML)", + "contentHint": "A valid pipeline: YAML definition.", + "readOnly": "System pipeline — read-only. You can only enable or disable it.", + "test": "Test", + "save": "Save", + "saving": "Saving…", + "delete": "Delete", + "confirmDelete": "Confirm delete", + "cancel": "Cancel" + }, + "toast": { + "saved": "Pipeline saved", + "saveError": "Failed to save pipeline", + "deleted": "Pipeline deleted", + "deleteError": "Failed to delete pipeline", + "activateError": "Failed to change pipeline state", + "nameRequired": "Name is required", + "contentRequired": "Content is required", + "orderError": "Failed to reorder pipeline" + }, + "visual": { + "visualTab": "Visual", + "codeTab": "Code", + "codeOnly": "Switch to Code — this content can't be shown visually.", + "cantParse": "Can't open the visual editor: {{error}}", + "dataTypes": "Data types", + "steps": "Steps", + "noSteps": "No steps yet.", + "addStep": "Add step:", + "removeStep": "Remove step", + "moveUp": "Move up", + "moveDown": "Move down", + "whereHint": "optional condition (CEL)", + "addValue": "Add value", + "addPattern": "Add pattern", + "rawHint": "This processor is edited as raw YAML.", + "rawNotMap": "Must be a set of key: value fields.", + "dataTypesPick": "Choose data types", + "dataTypesSearch": "Search data types…", + "dataTypesNone": "No data types", + "dataTypesAdd": "Add \"{{value}}\"", + "insertPattern": "Insert regex pattern", + "patternSearch": "Search patterns…", + "patternNone": "No patterns", + "newPattern": "New pattern…", + "createInsert": "Create & insert", + "patternCreated": "Pattern \"{{name}}\" created", + "patternCreateError": "Failed to create pattern", + "patternIdInvalid": "Pattern ID must start with a letter or _ and use only letters, digits or _", + "patternDefRequired": "Definition is required", + "parameters": "Parameters", + "paramsKey": "Key", + "paramsValue": "Value", + "entry": "Entry {{n}}", + "order": "order {{n}}", + "orderLabel": "Order", + "removeEntry": "Remove entry", + "addEntry": "Add pipeline entry", + "collapse": "Collapse", + "expand": "Expand", + "splitHint": "Blank defaults to a single space — the YAML always shows it as fieldSplit: \" \"." + }, + "allDataTypes": "All data types", + "testPipeline": "Test pipeline" + }, + "playground": { + "titleFilter": "Test pipeline", + "titleRule": "Test rule", + "noDataTypes": "This pipeline has no data types assigned yet — add one to test it.", + "dataTypeLabel": "Data type", + "dataTypePlaceholder": "No data types available", + "dataTypeSingleHint": "This pipeline only has one data type — add more to choose between them.", + "rawLogLabel": "Raw log", + "rawLogPlaceholder": "Paste a sample raw log line…", + "rawLogCounter": "{{chars}} chars · {{kb}} KB", + "rawLogTooLarge": "This log exceeds the 1 MB limit — trim it before running the test.", + "run": { + "label": "Run", + "running": "Testing…", + "waitHint": "This can take up to 15 seconds while the pipeline processes the log." + }, + "errors": { + "busy": "The playground is busy running another test — please try again shortly.", + "timeout": "The test timed out — this usually means the selected data type doesn't match the log format.", + "validation": "The request was invalid — check the raw log and pipeline content.", + "server": "The playground couldn't complete the test — please try again." + }, + "notices": { + "geo": "The geolocation plugin isn't available in this lite version of the filter and rule test.", + "correlation": "Rules that reference prior events through afterEvent or correlation clauses require matching historical events to already exist in the system for the tested alert to trigger." + }, + "result": { + "label": "Parsed result", + "empty": "Run a test to see the parsed event here.", + "loading": "Waiting for the parsed event…", + "tabs": { + "fields": "Fields", + "json": "JSON" + }, + "fieldsCount_one": "{{count}} field", + "fieldsCount_other": "{{count}} fields", + "copy": "Copy", + "copied": "Copied", + "elapsed": "Parsed in {{time}}", + "elapsedHint": "Time from Run to the parsed result", + "searchPlaceholder": "Search fields…", + "noMatch": "No fields match your search." + }, + "alerts": { + "label": "Alerts", + "empty": "Run a test to see any resulting alerts here.", + "none": "No alerts were triggered.", + "count_one": "{{count}} alert", + "count_other": "{{count}} alerts" + }, + "title": "Test pipeline" + }, + "alertingRules": { + "title": "Alerting Rules", + "subtitle": "Correlation rules that turn events into alerts. Toggle, tune or author your own.", + "new": "New rule", + "test": "Test", + "refresh": "Refresh", + "empty": "No rules match.", + "loadError": "Could not load the rules.", + "retry": "Retry", + "deleteConfirm": "Delete the rule “{{name}}”?", + "adversary": { + "origin": "Origin", + "target": "Target" + }, + "state": { + "active": "Active", + "inactive": "Inactive" + }, + "owner": { + "system": "System", + "custom": "Custom" + }, + "toolbar": { + "search": "Search rules…", + "allCategories": "All categories", + "allAdversaries": "All adversaries", + "allStates": "All states", + "allOwners": "All owners", + "allDataTypes": "All data types" + }, + "table": { + "name": "Rule", + "category": "Category", + "technique": "Technique", + "adversary": "Adversary", + "impact": "Impact", + "active": "Active", + "dataTypes": "Data types", + "selectAll": "Select all", + "selectRow": "Select {{name}}" + }, + "export": { + "all": "Export All", + "selected": "Export ({{count}})", + "error": "Could not export the rules" + }, + "view": { + "description": "Description", + "details": "Details", + "impact": "Impact (C·I·A)", + "dataTypes": "Data types", + "updated": "Updated", + "relPath": "Path", + "definition": "Condition (CEL)", + "correlationSteps": "Correlation steps", + "correlation": "Correlation", + "groupBy": "Group by", + "deduplicateBy": "Deduplicate by", + "references": "References" + }, + "editor": { + "createTitle": "New rule", + "edit": "Edit", + "delete": "Delete", + "export": "Export", + "cancel": "Cancel", + "save": "Save", + "test": "Test", + "metadata": "Metadata", + "name": "Name", + "confidentiality": "Confidentiality", + "integrity": "Integrity", + "availability": "Availability", + "dataTypes": "Data types", + "dataTypesHint": "comma-separated", + "activeOnSave": "Active", + "definitionSection": "Definition", + "where": "Condition (CEL)", + "whereHint": "CEL expression evaluated per event", + "correlationSteps": "Correlation steps", + "correlationStepsHint": "JSON array", + "jsonArray": "JSON array", + "nameRequired": "Name is required", + "definitionRequired": "The condition is required", + "invalidJson": "A definition field has invalid JSON", + "addStep": "Add correlation step", + "step": "Step {{n}}", + "removeStep": "Remove step", + "indexPattern": "Index pattern", + "within": "Within", + "count": "Count", + "conditions": "Conditions", + "field": "Field", + "value": "Value", + "addCondition": "Add condition", + "orGroup": "Or group {{n}}", + "addOr": "Add Or group", + "removeOr": "Remove", + "fieldsHint": "field names", + "referencesHint": "URLs", + "visual": "Visual", + "code": "Code", + "dataTypesPick": "Select…", + "dataTypesSearch": "Search data types…", + "dataTypesNone": "No data types", + "visualTab": "Visual", + "codeTab": "Code", + "yamlError": "Can't apply the YAML: {{error}}" + }, + "toast": { + "activated": "Rule activated", + "deactivated": "Rule deactivated", + "toggleError": "Could not change the rule state", + "deleted": "Rule deleted", + "deleteError": "Could not delete the rule", + "created": "Rule created", + "saved": "Rule saved", + "saveError": "Could not save the rule" + }, + "operator": { + "filter_term": "equals (term)", + "must_not_term": "not equals (term)", + "filter_match": "matches (text)", + "must_not_match": "not matches (text)" + }, + "where": { + "matchPrefix": "Match", + "all": "all", + "any": "any", + "matchSuffix": "of these conditions:", + "negate": "Negate", + "listHint": "comma-separated", + "advanced": "This condition uses advanced CEL — edit it in Code, or rebuild it visually.", + "and": "AND", + "or": "OR" + }, + "celOp": { + "exists": "exists", + "equals": "equals", + "equalsIgnoreCase": "equals (no case)", + "contains": "contains", + "oneOf": "is one of", + "containsAll": "contains all", + "startsWith": "starts with", + "endsWith": "ends with", + "regexMatch": "matches regex", + "lessThan": "<", + "lessOrEqual": "≤", + "greaterThan": ">", + "greaterOrEqual": "≥", + "inCIDR": "in CIDR", + "isHour": "hour is", + "isMinute": "minute is", + "isDayOfWeek": "day of week is", + "isWeekend": "is weekend", + "isWorkDay": "is workday", + "isBetweenTime": "time between" + }, + "import": { + "button": "Import", + "error": "Import failed", + "resultTitle": "Import results", + "approved": "Approved", + "rejected": "Rejected", + "done": "Done" + } }, - "resource": { - "pipeline": "pipeline", - "correlationRule": "correlation rule", - "soarFlow": "SOAR flow", - "framework": "framework", - "control": "control", - "smtp": "SMTP", - "idp": "identity provider", - "branding": "branding" + "regexPatterns": { + "title": "Regex Patterns", + "subtitle": "Reusable regular expressions referenced by parsing filters.", + "new": "New pattern", + "search": "Search patterns…", + "refresh": "Refresh", + "view": "View", + "system": "System", + "user": "Custom", + "loading": "Loading patterns…", + "loadError": "Could not load patterns.", + "retry": "Retry", + "empty": "No patterns match this view.", + "tabs": { + "all": "All", + "system": "System", + "user": "Custom" + }, + "cols": { + "pattern": "Pattern", + "definition": "Definition", + "type": "Type" + }, + "editor": { + "titleNew": "New pattern", + "patternId": "Pattern ID", + "patternIdHint": "Unique name referenced from filters.", + "description": "Description", + "descriptionPlaceholder": "What this pattern matches (optional)", + "definition": "Definition (regex)", + "definitionHint": "A regular expression. Can reference other patterns.", + "readOnly": "System pattern — read-only.", + "save": "Save", + "saving": "Saving…", + "delete": "Delete", + "confirmDelete": "Confirm delete", + "cancel": "Cancel" + }, + "toast": { + "saved": "Pattern saved", + "saveError": "Failed to save pattern", + "deleted": "Pattern deleted", + "deleteError": "Failed to delete pattern", + "patternIdRequired": "Pattern ID is required", + "definitionRequired": "Definition is required" + } }, - "warning": { - "title": "This action will run on every selected tenant.", - "body": "Per-tenant failures are reported after the run and are not rolled back." + "soar": { + "title": "SOAR", + "subtitle": "Automated alert-response flows: conditions match an alert, commands run on the agent.", + "comingSoon": "Coming soon", + "console": { + "loading": "Loading agents…", + "loadError": "Could not load agents.", + "pickAgent": "Select an agent", + "pickAgentHint": "Choose an agent from the list to open its interactive console.", + "lockedAgent": "Remote control disabled" + }, + "search": "Search flows…", + "refresh": "Refresh", + "new": "New flow", + "view": "View", + "system": "System", + "loading": "Loading flows…", + "loadError": "Could not load flows.", + "retry": "Retry", + "empty": "No flows match this view.", + "templates": { + "title": "Start a new flow", + "subtitle": "Pick an action template or start from scratch.", + "loading": "Loading templates…", + "loadError": "Could not load templates.", + "empty": "No templates available.", + "cancel": "Cancel", + "scratch": "Start from scratch" + }, + "tabs": { + "flows": "Flows", + "executions": "Execution history", + "all": "All", + "active": "Active", + "inactive": "Inactive", + "system": "System", + "user": "Custom" + }, + "cols": { + "flow": "Flow", + "platform": "Platform", + "conditions": "Conditions", + "commands": "Commands", + "active": "Active", + "lastRun": "Last run", + "failedRuns_one": "{{count}} failed run", + "failedRuns_other": "{{count}} failed runs" + }, + "operator": { + "IS": "is", + "IS_NOT": "is not", + "CONTAINS": "contains", + "NOT_CONTAINS": "does not contain", + "EXISTS": "exists", + "NOT_EXISTS": "does not exist", + "START_WITH": "starts with", + "NOT_START_WITH": "does not start with", + "ENDS_WITH": "ends with", + "NOT_ENDS_WITH": "does not end with", + "IS_ONE_OF": "is one of", + "IS_NOT_ONE_OF": "is not one of" + }, + "toast": { + "created": "Flow created", + "saved": "Flow saved", + "saveError": "Failed to save flow", + "deleted": "Flow deleted", + "deleteError": "Failed to delete flow", + "activateError": "Failed to change flow state" + }, + "editor": { + "createTitle": "New flow", + "visualTab": "Visual", + "codeTab": "Code", + "name": "Name", + "description": "Description", + "conditions": "Conditions", + "conditionsHint": "The flow runs when an alert matches ALL of these conditions.", + "field": "field", + "value": "value", + "valueList": "comma-separated values", + "addCondition": "Add condition", + "commands": "Commands", + "commandsHint": "Run in order on the agent. Use $(field.path) for alert values and $[variables.NAME] for stored variables.", + "addCommand": "Add command", + "templatesButton": "Common commands", + "templates": { + "isolate": "Isolate from network", + "shutdown": "Shutdown machine", + "killProcess": "Kill process", + "logout": "Log out user", + "disableUser": "Disable user", + "blockIp": "Block IP", + "restart": "Restart machine", + "uninstall": "Uninstall application" + }, + "connector": { + "always": "always", + "success": "on success", + "failure": "on failure" + }, + "agentPlatform": "Agent platform", + "shell": "Shell", + "shellAuto": "auto", + "whereToRun": "Where to run", + "run": { + "all": "All agents", + "specific": "One agent", + "except": "All except", + "allHint": "Runs on every agent that matches this platform." + }, + "selectAgentPlaceholder": "Select an agent…", + "excludedAgentsHint": "type a hostname and press Enter", + "save": "Save", + "delete": "Delete", + "confirmDelete": "Confirm delete", + "cancel": "Cancel", + "yamlError": "Can't apply the YAML: {{error}}", + "nameRequired": "Name is required", + "conditionsRequired": "At least one condition with a field is required", + "commandsRequired": "At least one command is required", + "httpUrlInvalid": "HTTP node \"{{id}}\" has an invalid URL — must be a valid http(s) URL.", + "httpBodyInvalid": "HTTP node \"{{id}}\" body is not valid JSON: {{error}}", + "incidentNameRequired": "Incident node \"{{id}}\" needs a name.", + "mailToRequired": "Email node \"{{id}}\" needs at least one recipient.", + "mailAddressInvalid": "Email node \"{{id}}\" has an invalid {{field}} address: {{address}}.", + "mailSubjectRequired": "Email node \"{{id}}\" needs a subject.", + "identityModalTitle": "Flow details", + "platformRequired": "Agent platform is required", + "nameLabel": "Name", + "namePlaceholder": "Flow name", + "descriptionLabel": "Description", + "descriptionHint": "What does this flow do? (optional)", + "when": "When", + "whenTitle": "An alert matches all of these conditions", + "on": "On", + "onTitle": "The matching agent", + "thenRun": "Then run", + "thenTitle": "These commands, in order", + "selectField": "Select a field…", + "selectPlatform": "Select a platform…", + "searchAgents": "Search agents…", + "noAgents": "No agents", + "insertInto": "Insert into command {{n}}:", + "insertField": "Alert field", + "variables": "Variables", + "canvas": { + "node": "Node", + "deleteNode": "Delete node", + "id": "ID", + "kind": "Kind", + "executor": "Executor", + "commandLabel": "Command", + "paramsJson": "Params (JSON)", + "dragToResize": "Drag to resize", + "templatesLabel": "Templates", + "templatesNeedPlatform": "First select target platform", + "handlesHint": "Drag from the bottom-left green handle for on_success, the bottom-right red handle for on_error. Multiple wires = parallel. Multiple wires into one node = AND-join.", + "invalidJson": "invalid JSON", + "hidePalette": "Hide palette", + "hideInspector": "Hide inspector", + "paletteLabel": "Palette", + "nodeShort": "Node", + "showPanel": "Show {{name}}", + "platform": "Platform", + "shell": "Shell", + "any": "any", + "auto": "auto", + "runOn": "Run on", + "runAutoTitle": "Runs on the host that raised the alert", + "runSpecificTitle": "Pin to one host (or a template like $(alert.foo))", + "runExceptTitle": "Runs on the host that raised the alert, but skips ones in the list", + "runAutoLabel": "alert source", + "runSpecificLabel": "one host", + "runExceptLabel": "all except", + "runAutoHint": "Runs on $(alert.dataSource) — the host that raised the matched alert.", + "pickHost": "pick a host…", + "orTemplateHint": "Or type a template — $(alert.field) resolves per execution.", + "addExclusion": "add exclusion", + "searchAgents": "search agents…", + "noAgents": "no agents", + "insertField": "Insert field", + "alert": "Alert", + "wholeOutput": "whole output (edit the path)", + "noAncestorsHint": "No enrichment ancestors yet — add an enrichment node upstream to expose its output here.", + "inserts": "inserts", + "conditionalHint": "All conditions must match. Match → success branch (green); miss → error branch (red).", + "http": { + "url": "URL", + "urlInvalid": "Not a valid http(s) URL.", + "method": "Method", + "body": "Body (JSON)", + "bodyInvalid": "Invalid JSON", + "headers": "HTTP headers", + "params": "Query params", + "key": "Key", + "value": "Value", + "addHeader": "Add header", + "addParam": "Add param" + }, + "incident": { + "name": "Incident name", + "namePlaceholder": "e.g. Suspicious login on $(alert.dataSource)", + "description": "Description", + "descriptionPlaceholder": "Optional context for responders. Templates like $(alert.name) are interpolated." + }, + "llm": { + "prompt": "Prompt", + "hint": "The model is instructed to always answer with a single JSON object carrying a \"result\" property. The backend guarantees this shape even if the model deviates. Child nodes reference it via $({{nodeId}}.result) or specific fields." + }, + "mail": { + "to": "To (comma-separated)", + "cc": "CC (comma-separated, optional)", + "addressInvalid": "Invalid email address: {{address}}", + "subject": "Subject", + "subjectPlaceholder": "e.g. Alert on $(alert.dataSource)", + "body": "Body", + "bodyPlaceholder": "Message body. Templates like $(alert.name) are interpolated." + }, + "notify": { + "level": "Level", + "message": "Message", + "messagePlaceholder": "Notification text. Templates like $(alert.name) are interpolated." + } + } + }, + "executions": { + "search": "Search by alert ID…", + "all": "All", + "loading": "Loading executions…", + "loadError": "Could not load executions.", + "retry": "Retry", + "empty": "No executions yet.", + "cols": { + "status": "Status", + "flow": "Flow", + "command": "Command / Action", + "agent": "Agent", + "date": "Date", + "retries": "Retries", + "node": "Node" + }, + "filters": { + "source": "Source", + "allSources": "All sources" + }, + "manual": "Interactive console" + }, + "executionStatus": { + "WAITING": "Waiting", + "PENDING": "Pending", + "EXECUTING": "Executing", + "EXECUTED": "Executed", + "FAILED": "Failed", + "DEAD": "Unreachable" + }, + "executionOrigin": { + "FLOW": "Flow", + "MANUAL": "Manual" + }, + "nonExecutionCause": { + "AGENT_OFFLINE": "Agent offline", + "AGENT_NOT_FOUND": "Agent not found", + "UNKNOWN": "Unknown" + }, + "kpi": { + "flows": "Total flows", + "active": "Active", + "runs24h": "Executions (24h)", + "failed24h": "Failed (24h)" + }, + "neverRun": "never", + "create": { + "title": "New flow", + "modeManual": "Create manually", + "modeAi": "Using AI", + "aiLocked": "Enable SOC-AI and configure it to use this.", + "name": "Flow name", + "namePlaceholder": "e.g. Block IP on repeated failures", + "aiDescriptionLabel": "What should this flow do?", + "aiDescriptionPlaceholder": "e.g. On a critical alert, look up the source IP in threat intel and block it on the firewall", + "aiCreate": "Create with AI", + "manualContinue": "Continue" + } }, - "allTenants": "Apply to all tenants", - "excludesDefault": "The platform-plane tenant is excluded from this action.", - "searchPlaceholder": "Search tenants…", - "loading": "Loading tenants…", - "empty": "No tenants match.", - "targetCount": "Will target {{count}} tenant(s).", - "platformTenant": "platform", - "confirm": "Apply to {{count}} tenant(s)", - "result": { - "succeeded": "Succeeded", - "noneSucceeded": "No tenants succeeded.", - "failed": "Failed", - "noneFailed": "No failures." - } - }, - "tiAnalyst": { - "console": { - "subtitle": "Analyst workspace", - "model": "Model", - "resizeResults": "Resize the results pane", - "resizeHint": "Drag to resize · double-click to reset" + "compliance": { + "title": "Compliance", + "subtitle": "Evaluate your posture against security frameworks — see which controls are met and which aren't.", + "comingSoon": "Coming soon.", + "tabs": { + "frameworks": "Frameworks", + "schedule": "Schedule", + "controls": "Controls" + }, + "search": "Search frameworks…", + "refresh": "Refresh", + "loading": "Loading frameworks…", + "loadError": "Could not load reports", + "retry": "Retry", + "empty": "No frameworks match.", + "notEvaluated": "Not evaluated", + "controlsCount": "{{n}} controls", + "enabledLabel": "Enabled", + "runReport": "Run report", + "backToFrameworks": "Back to frameworks", + "statusAuto": "Auto (evaluated)", + "overrideError": "Failed to update status", + "noteError": "Could not save the note", + "notes": { + "title": "Notes", + "placeholder": "Add a note…", + "save": "Save", + "cancel": "Cancel" + }, + "reasonModal": { + "title": "Reason required", + "description": "Provide a reason for this status change. It will be recorded.", + "label": "Reason", + "placeholder": "Explain why you are changing this control's status…", + "confirm": "Confirm change", + "cancel": "Cancel" + }, + "coverageLabel": "Coverage", + "activityLabel": "Activity", + "evidenceLabel": "Evidence", + "seeMore": "See more", + "seeLess": "See less", + "evaluating": "Evaluating framework…", + "complianceScore": "Compliance score", + "generatedAt": "Generated {{date}}", + "reportError": "Could not generate the report.", + "coverage": "{{n}} rules", + "activity": "{{n}} alerts", + "status": { + "COMPLIANT": "Compliant", + "NON_COMPLIANT": "Non-compliant", + "AT_RISK": "At risk", + "NOT_COVERED": "Not covered", + "OUT_OF_SCOPE": "Out of scope", + "PENDING": "Pending", + "label": "Status", + "NOT_EVALUATED": "Not evaluated" + }, + "toast": { + "toggleError": "Failed to change framework state", + "reportGenerated": "Report generated", + "reportError": "Failed to generate report" + }, + "schedule": { + "new": "New schedule", + "loading": "Loading schedules…", + "loadError": "Could not load schedules.", + "empty": "No schedules yet.", + "edit": "Edit", + "delete": "Delete", + "newTitle": "New schedule", + "editTitle": "Edit schedule", + "framework": "Framework", + "cadenceLabel": "Cadence", + "cronHint": "5-field cron (min hour day month weekday).", + "recipientsHint": "Comma-separated emails. Leave empty to only store the snapshot.", + "save": "Save", + "cancel": "Cancel", + "frameworkRequired": "Framework is required", + "cronRequired": "Schedule (cron) is required", + "cadence": { + "daily": "Daily", + "weekly": "Weekly", + "monthly": "Monthly", + "custom": "Custom" + }, + "toast": { + "saved": "Schedule saved", + "saveError": "Failed to save schedule", + "deleted": "Schedule deleted", + "deleteError": "Failed to delete schedule" + }, + "to": "To", + "cc": "Cc", + "toRequired": "At least one recipient is required", + "windowDays": "Reporting window (days)", + "windowDaysShort": "over {{days}}d", + "windowDaysHint": "How far back the report counts. Independent of how often it runs." + }, + "frameworks": { + "new": "New framework", + "edit": "Edit", + "createTitle": "New framework", + "visualTab": "Visual", + "codeTab": "Code", + "key": "Key", + "name": "Name", + "description": "Description", + "source": "Source", + "sections": "Sections", + "sectionKey": "section key", + "sectionName": "Section name", + "requirements": "Requirements", + "reqId": "req id", + "reqName": "Requirement name", + "addSection": "Add section", + "addRequirement": "Add requirement", + "satisfiedBy": "satisfied by controls", + "searchControls": "Search controls…", + "noControls": "No controls", + "save": "Save", + "delete": "Delete", + "confirmDelete": "Confirm delete", + "cancel": "Cancel", + "yamlError": "Can't apply the YAML: {{error}}", + "keyRequired": "Key is required", + "nameRequired": "Name is required", + "toast": { + "created": "Framework created", + "saved": "Framework saved", + "saveError": "Failed to save framework", + "deleted": "Framework deleted", + "deleteError": "Failed to delete framework" + }, + "createControl": "Create new control…", + "createNamed": "Create control \"{{name}}\"…" + }, + "controls": { + "search": "Search controls…", + "allFamilies": "All families", + "new": "New control", + "loading": "Loading controls…", + "loadError": "Could not load controls.", + "empty": "No controls match.", + "showingOf": "Showing {{shown}} of {{total}}", + "id": "ID", + "name": "Name", + "family": "Family", + "familyName": "Family", + "scope": "Scope", + "source": "Source", + "notInLibrary": "Control not found in library", + "scopeOpt": { + "data": "Data", + "governance": "Governance" + }, + "strategy": "Strategy", + "statement": "Statement", + "remediation": "Remediation", + "checks": "Checks", + "checksHint": "Each check runs an OpenSearch SQL query and applies a rule to decide pass/fail.", + "checkKey": "key", + "checkName": "Check name", + "rule": { + "MIN_HITS_REQUIRED": "Min hits required", + "THRESHOLD_MAX": "Threshold max" + }, + "ruleNone": "No rule", + "ruleValue": "value", + "addCheck": "Add check", + "createTitle": "New control", + "visualTab": "Visual", + "codeTab": "Code", + "save": "Save", + "delete": "Delete", + "confirmDelete": "Confirm delete", + "cancel": "Cancel", + "yamlError": "Can't apply the YAML: {{error}}", + "idRequired": "ID is required", + "nameRequired": "Name is required", + "anyDataType": "Any data type", + "addFilter": "Add filter", + "filterField": "log.eventCode", + "filterValue": "value", + "filterValues": "a, b, c", + "toast": { + "created": "Control created", + "saved": "Control saved", + "saveError": "Failed to save control", + "deleted": "Control deleted", + "deleteError": "Failed to delete control" + } + }, + "doc": { + "title": "Compliance Report", + "print": "Print / PDF", + "controlsEvaluated": "{{n}} controls evaluated", + "executiveSummary": "Executive Summary", + "bySection": "Findings by Section", + "footer": "{{framework}} — Compliance report generated {{date}} · {{brand}}", + "download": "Download PDF", + "downloadError": "Failed to download the PDF", + "error": "Could not generate the PDF", + "building": "Building the document…" + }, + "locked": { + "badge": "Enterprise", + "upgrade": "Upgrade to Enterprise", + "upsell": "This framework/control requires the Enterprise edition." + }, + "run": "Run evaluation", + "runError": "Evaluation failed", + "noReportYet": "This framework has not been evaluated yet.", + "window": "window {{from}} → {{to}}", + "scoredOver": "{{compliant}} of {{evaluated}} requirements met · {{total}} in the framework", + "editStale": "Recorded when the engine said {{was}}; it now says {{now}}", + "checkResults": "Check results", + "verdict": "Recorded verdict", + "engineSaid": "engine said", + "hits": "hits", + "noDataFor": "no {{dataType}} data in the window", + "setStatus": "Set status", + "outcome": { + "PASSED": "Passed", + "FAILED": "Failed", + "NOT_APPLICABLE": "No data", + "ERROR": "Error" + }, + "system": "Shipped", + "addNote": "Add a note", + "noteModal": { + "title": "Note", + "description": "Recorded on the report. It does not change the control’s status.", + "placeholder": "Remediation in progress — ticket OPS-4412, due end of quarter." + }, + "history": { + "title": "Score over time", + "score": "Compliance score", + "coverage": "Evaluated", + "error": "Could not load the score history" + } }, - "conv": { - "title": "Conversations", - "allConversations": "All conversations", - "empty": "No conversations yet.", - "new": "New conversation", - "newTitle": "Conversation title", - "selectPrompt": "Select a conversation, or start one.", - "running": "running", - "delete": "Delete {{title}}", - "unread_one": "{{count}} unread message", - "unread_other": "{{count}} unread messages", - "transcript": "Conversation transcript" + "tenants": { + "title": "Tenants", + "new": "New tenant", + "subtitle": "Every customer running on this instance, what they hold and what they let you see.", + "searchPlaceholder": "Search by name or domain…", + "loading": "Loading tenants…", + "loadFailed": "Could not load tenants.", + "retry": "Retry", + "none": "No tenants yet.", + "noSearchMatch": "No tenants match your search.", + "cancel": "Cancel", + "saving": "Saving…", + "chips": { + "total": "tenants", + "active": "active", + "readable": "readable" + }, + "status": { + "ACTIVE": "Active", + "SUSPENDED": "Suspended", + "TERMINATED": "Terminated" + }, + "support": { + "NONE": "No access", + "READ": "Read access", + "FULL": "Full access", + "hint": "Granted by the tenant, not by you. Only their administrator can change it." + }, + "card": { + "edit": "Edit", + "activate": "Activate", + "deactivate": "Deactivate", + "deletePermanent": "Delete permanently", + "noAccess": "This tenant has not granted you access.", + "loadingStats": "Reading…", + "enter": "Enter" + }, + "stats": { + "users": "Users", + "datasources": "Sources", + "openAlerts": "Open alerts", + "ai": "AI today", + "noLimit": "no cap" + }, + "fields": { + "name": "Name", + "domain": "Domain", + "domainHint": "How this tenant is reached. Every request on this host lands in their data.", + "adminEmail": "Administrator email", + "adminEmailHint": "They get an invitation to set their own password.", + "status": "Status", + "suspendedWarning": "Suspended tenants cannot sign in. Their data is kept.", + "aiLimit": "AI request cap", + "aiLimitHint": "An operational cap, per day. Uncapped, they spend against the instance licence.", + "aiLimitToggle": "Cap this tenant" + }, + "create": { + "title": "New tenant", + "subtitle": "Creates the tenant and invites its first administrator.", + "submit": "Create tenant" + }, + "edit": { + "title": "Edit tenant", + "subtitle": "Support access is not here: only the tenant can grant it.", + "submit": "Save changes" + }, + "terminate": { + "title": "Deactivate this tenant?", + "body": "Nobody in {{name}} will be able to sign in. Their data is kept, so this is reversible, but it takes the customer offline now.", + "confirmLabel": "Type {{name}} to confirm", + "submit": "Deactivate" + }, + "reactivate": { + "title": "Activate this tenant?", + "body": "{{name}} will be able to sign in again. Their preserved data is restored as-is.", + "submit": "Activate" + }, + "deletePermanent": { + "title": "Delete this tenant forever?", + "body": "Every trace of {{name}} — users, data sources, dashboards, alerts, integrations — will be erased. This cannot be undone.", + "confirmLabel": "Type {{name}} to confirm", + "submit": "Delete forever" + }, + "toast": { + "created": "Tenant created", + "updated": "Tenant updated", + "terminated": "Tenant terminated", + "reactivated": "Tenant reactivated", + "permanentlyDeleted": "Tenant permanently deleted", + "domainInUse": "That domain is already taken", + "noPermission": "You do not have permission to do that", + "notFound": "Tenant not found", + "invalidRequest": "Invalid request", + "operationFailed": "Operation failed" + }, + "switcher": { + "aria": "Switch tenant", + "self": "Default tenant", + "create": "Create tenant" + } }, - "agent": { - "placeholder": "Investigate an indicator…", - "ask": "Ask the analyst agent", - "intro": "Ask about any indicator. The agent queries ThreatWinds directly and shows its work.", - "send": "Send", - "stop": "Stop", - "thinking": "thinking…", - "suggestionInvestigate": "Investigate 8.8.8.8 and tell me if it is malicious", - "suggestionInfrastructure": "What infrastructure is related to google.com?", - "suggestionCounts": "Show me how many entities exist per type" + "supportAccess": { + "title": "Support access", + "intro": "Whoever operates this instance cannot look inside your data unless you let them. Nothing here is granted by default, and you can take it back at any time.", + "loading": "Loading…", + "loadFailed": "Could not read the current setting.", + "retry": "Retry", + "currentBadge": "current", + "save": "Save", + "saving": "Saving…", + "levels": { + "NONE": { + "name": "No access", + "desc": "The operator sees that your tenant exists and nothing else. Requests into your data are refused." + }, + "READ": { + "name": "Read only", + "desc": "The operator can look at your alerts, logs and configuration to help you. They cannot change anything — every write is refused, whatever their own role says." + }, + "FULL": { + "name": "Full access", + "desc": "The operator can act inside your tenant as an administrator: change configuration, users and response flows." + } + }, + "fullWarning": "Full access lets the operator change things on your behalf. Grant it while you need hands-on help, and drop back afterwards.", + "revokeNote": "Everything the operator does here is recorded in your audit log.", + "toast": { + "granted": "Support access updated", + "revoked": "Support access revoked", + "forbidden": "Only an administrator of this tenant can change this", + "invalid": "Invalid request", + "failed": "Could not save the change" + } }, - "canvas": { - "title": "Results", - "empty": "Results from this conversation appear here.", - "tile": "Tile", - "closeAll": "Close all", - "pinOut": "Open {{title}} as panel", - "loading": "loading…", - "failed": "could not load", - "noRelations": "no related entities", - "noGeo": "no geolocation recorded", - "noResults": "no matches", - "matches": "{{total}} matches", - "panelName": "{{title}} — {{kind}}", - "movePanel": "Move {{title}}", - "resizePanel": "Resize {{title}}", - "closePanel": "Close {{title}}", - "collapse": "Collapse {{title}}", - "expand": "Expand {{title}}", - "kind": { - "entity": "dossier", - "graph": "relations", - "geo": "geolocation", - "search": "search" - } + "supportSession": { + "inside": "You are working inside {{name}}", + "readOnly": "read only — writes are refused", + "full": "full access — changes here are real", + "leave": "Leave" + }, + "platformBroadcast": { + "button": "Apply to all tenants", + "action": { + "create": "Broadcast {{resource}} create", + "update": "Broadcast {{resource}} update", + "delete": "Broadcast {{resource}} delete", + "toggle": "Broadcast {{resource}} toggle", + "enable": "Broadcast {{resource}} enable", + "activate": "Broadcast {{resource}} activate", + "test": "Broadcast {{resource}} test", + "upload": "Broadcast {{resource}} asset" + }, + "resource": { + "pipeline": "pipeline", + "correlationRule": "correlation rule", + "soarFlow": "SOAR flow", + "framework": "framework", + "control": "control", + "smtp": "SMTP", + "idp": "identity provider", + "branding": "branding" + }, + "warning": { + "title": "This action will run on every selected tenant.", + "body": "Per-tenant failures are reported after the run and are not rolled back." + }, + "allTenants": "Apply to all tenants", + "excludesDefault": "The platform-plane tenant is excluded from this action.", + "searchPlaceholder": "Search tenants…", + "loading": "Loading tenants…", + "empty": "No tenants match.", + "targetCount": "Will target {{count}} tenant(s).", + "platformTenant": "platform", + "confirm": "Apply to {{count}} tenant(s)", + "result": { + "succeeded": "Succeeded", + "noneSucceeded": "No tenants succeeded.", + "failed": "Failed", + "noneFailed": "No failures." + } }, - "graph": { - "nodes_one": "{{count}} node", - "nodes_other": "{{count}} nodes", - "edges_one": "{{count}} edge", - "edges_other": "{{count}} edges", - "clickToPivot": "click to pivot", - "malicious": "malicious", - "unknown": "unknown", - "benign": "benign" + "tiAnalyst": { + "console": { + "subtitle": "Analyst workspace", + "model": "Model", + "resizeResults": "Resize the results pane", + "resizeHint": "Drag to resize · double-click to reset" + }, + "conv": { + "title": "Conversations", + "allConversations": "All conversations", + "empty": "No conversations yet.", + "new": "New conversation", + "newTitle": "Conversation title", + "selectPrompt": "Select a conversation, or start one.", + "running": "running", + "delete": "Delete {{title}}", + "unread_one": "{{count}} unread message", + "unread_other": "{{count}} unread messages", + "transcript": "Conversation transcript" + }, + "agent": { + "placeholder": "Investigate an indicator…", + "ask": "Ask the analyst agent", + "intro": "Ask about any indicator. The agent queries ThreatWinds directly and shows its work.", + "send": "Send", + "stop": "Stop", + "thinking": "thinking…", + "suggestionInvestigate": "Investigate 8.8.8.8 and tell me if it is malicious", + "suggestionInfrastructure": "What infrastructure is related to google.com?", + "suggestionCounts": "Show me how many entities exist per type" + }, + "canvas": { + "title": "Results", + "empty": "Results from this conversation appear here.", + "tile": "Tile", + "closeAll": "Close all", + "pinOut": "Open {{title}} as panel", + "loading": "loading…", + "failed": "could not load", + "noRelations": "no related entities", + "noGeo": "no geolocation recorded", + "noResults": "no matches", + "matches": "{{total}} matches", + "panelName": "{{title}} — {{kind}}", + "movePanel": "Move {{title}}", + "resizePanel": "Resize {{title}}", + "closePanel": "Close {{title}}", + "collapse": "Collapse {{title}}", + "expand": "Expand {{title}}", + "kind": { + "entity": "dossier", + "graph": "relations", + "geo": "geolocation", + "search": "search" + } + }, + "graph": { + "nodes_one": "{{count}} node", + "nodes_other": "{{count}} nodes", + "edges_one": "{{count}} edge", + "edges_other": "{{count}} edges", + "clickToPivot": "click to pivot", + "malicious": "malicious", + "unknown": "unknown", + "benign": "benign" + }, + "entity": { + "reputation": "Reputation", + "accuracy": "Accuracy", + "worst": "Worst", + "best": "Best", + "relations": "Relationship graph", + "history": "History", + "geolocations": "Geolocations", + "associations": "Associations", + "radius": "r={{radius}}m", + "askAgentBtn": "Ask agent", + "askAgent": "Assess {{type}} {{value}} (entity id {{id}}). Is it a threat?" + }, + "tool": { + "querying": "querying…", + "notRetained": "Result not kept.", + "expand": "Show request and result", + "collapse": "Hide request and result", + "noIntel": "\"{{value}}\" has no threat intelligence recorded.", + "noMatches": "No matches.", + "matches": "{{items}} matches for \"{{query}}\"", + "more": "+{{count}} more", + "reported": "Reported to the shared ThreatWinds corpus. Ingestion is asynchronous, not immediately searchable.", + "skippedAssociations": "Not recorded (type could not be inferred): {{values}}" + } }, - "entity": { - "reputation": "Reputation", - "accuracy": "Accuracy", - "worst": "Worst", - "best": "Best", - "relations": "Relationship graph", - "history": "History", - "geolocations": "Geolocations", - "associations": "Associations", - "radius": "r={{radius}}m", - "askAgentBtn": "Ask agent", - "askAgent": "Assess {{type}} {{value}} (entity id {{id}}). Is it a threat?" + "threatwinds": { + "title": "ThreatWinds Integration", + "subtitle": "Share this instance's incidents with the ThreatWinds community feed.", + "feeds": "Enable feeds", + "feedsHint": "When on, events are checked against ThreatWinds intelligence feeds.", + "contribute": "Contribute incidents", + "contributeHint": "When on, incidents from this instance are sent to ThreatWinds.", + "loading": "Loading integration status…", + "failed": "Could not load the ThreatWinds integration status.", + "retry": "Retry", + "toast": { + "enabled": "Contribution enabled", + "disabled": "Contribution disabled", + "failed": "Could not update the contribution setting" + } }, - "tool": { - "querying": "querying…", - "notRetained": "Result not kept.", - "expand": "Show request and result", - "collapse": "Hide request and result", - "noIntel": "\"{{value}}\" has no threat intelligence recorded.", - "noMatches": "No matches.", - "matches": "{{items}} matches for \"{{query}}\"", - "more": "+{{count}} more", - "reported": "Reported to the shared ThreatWinds corpus. Ingestion is asynchronous, not immediately searchable.", - "skippedAssociations": "Not recorded (type could not be inferred): {{values}}" - } - }, - "threatwinds": { - "title": "ThreatWinds Integration", - "subtitle": "Share this instance's incidents with the ThreatWinds community feed.", - "feeds": "Enable feeds", - "feedsHint": "When on, events are checked against ThreatWinds intelligence feeds.", - "contribute": "Contribute incidents", - "contributeHint": "When on, incidents from this instance are sent to ThreatWinds.", - "loading": "Loading integration status…", - "failed": "Could not load the ThreatWinds integration status.", - "retry": "Retry", - "toast": { - "enabled": "Contribution enabled", - "disabled": "Contribution disabled", - "failed": "Could not update the contribution setting" - } - }, - "liveOps": { - "header": "Live Operations", - "live": "LIVE", - "replay": "REPLAY", - "statLastHour": "Last hour", - "statHigh": "High", - "statOpen": "Open", - "statAttackers": "Attackers", - "listTitle": "Alerts", - "listShown": "{{count}} shown", - "listShow": "Show the alert list", - "listHide": "Hide the list", - "agoJust": "just now", - "agoMin": "{{count}} min ago", - "agoH": "{{count}} h ago", - "more": "More", - "less": "Less", - "loading": "Loading alerts…", - "error": "Could not load alerts: {{msg}}", - "empty": "No alerts in the store.", - "onStage": "On stage", - "hideDetails": "Hide this panel", - "showDetails": "Show the details", - "inIncident": "In an incident", - "openInAlerts": "Open in Alerts", - "involved": "Involved", - "askSocAi": "Ask SOC-AI", - "askExplain": "Explain this attack and tell me what to do next", - "askFp": "Is this a false positive?", - "askAttacker": "What else did this attacker do?", - "timCount": "{{count}} alerts in the last {{range}}", - "timPrev": "Previous alert", - "timNext": "Next alert", - "timReplay": "Replay window", - "timStop": "Stop replay", - "timLive": "LIVE", - "timNow": "now", - "kb": { - "bruteForce": "Brute force", - "outbound": "Connection to a malicious destination", - "lateral": "Lateral movement", - "malware": "Malicious execution on a host", - "webAttack": "Web attack", - "travel": "Impossible travel", - "scan": "Port scan", - "cloud": "Risky cloud change", - "ransomware": "Ransomware on a host", - "persistence": "Persistence mechanism", - "exfil": "Data exfiltration", - "defenseEvasion": "Defense evasion", - "privEsc": "Privilege escalation", - "generic": "Detection", - "userExec": "User opened a malicious file", - "softwareDeploy": "Software pushed to a host", - "phishing": "Phishing email opened", - "processInjection": "Code injected into a process", - "credDump": "Credentials dumped", - "dataDestruction": "Data destroyed", - "toolDownload": "Tool downloaded and executed", - "c2tunnel": "Tunneled command-and-control", - "iocMatch": "Threat intel IOC match", - "perimeterDetect": "Perimeter / IDS detection", - "accountChange": "Account or policy change", - "kerberosTicket": "Kerberos ticket abuse", - "powershellAbuse": "Scripting abuse", - "reverseShell": "Reverse shell", - "vmEscape": "VM / hypervisor escape" + "liveOps": { + "header": "Live Operations", + "live": "LIVE", + "replay": "REPLAY", + "statLastHour": "Last hour", + "statHigh": "High", + "statOpen": "Open", + "statAttackers": "Attackers", + "listTitle": "Alerts", + "listShown": "{{count}} shown", + "listShow": "Show the alert list", + "listHide": "Hide the list", + "agoJust": "just now", + "agoMin": "{{count}} min ago", + "agoH": "{{count}} h ago", + "more": "More", + "less": "Less", + "loading": "Loading alerts…", + "error": "Could not load alerts: {{msg}}", + "empty": "No alerts in the store.", + "onStage": "On stage", + "hideDetails": "Hide this panel", + "showDetails": "Show the details", + "inIncident": "In an incident", + "openInAlerts": "Open in Alerts", + "involved": "Involved", + "askSocAi": "Ask SOC-AI", + "askExplain": "Explain this attack and tell me what to do next", + "askFp": "Is this a false positive?", + "askAttacker": "What else did this attacker do?", + "timCount": "{{count}} alerts in the last {{range}}", + "timPrev": "Previous alert", + "timNext": "Next alert", + "timReplay": "Replay window", + "timStop": "Stop replay", + "timLive": "LIVE", + "timNow": "now", + "kb": { + "bruteForce": "Brute force", + "outbound": "Connection to a malicious destination", + "lateral": "Lateral movement", + "malware": "Malicious execution on a host", + "webAttack": "Web attack", + "travel": "Impossible travel", + "scan": "Port scan", + "cloud": "Risky cloud change", + "ransomware": "Ransomware on a host", + "persistence": "Persistence mechanism", + "exfil": "Data exfiltration", + "defenseEvasion": "Defense evasion", + "privEsc": "Privilege escalation", + "generic": "Detection", + "userExec": "User opened a malicious file", + "softwareDeploy": "Software pushed to a host", + "phishing": "Phishing email opened", + "processInjection": "Code injected into a process", + "credDump": "Credentials dumped", + "dataDestruction": "Data destroyed", + "toolDownload": "Tool downloaded and executed", + "c2tunnel": "Tunneled command-and-control", + "iocMatch": "Threat intel IOC match", + "perimeterDetect": "Perimeter / IDS detection", + "accountChange": "Account or policy change", + "kerberosTicket": "Kerberos ticket abuse", + "powershellAbuse": "Scripting abuse", + "reverseShell": "Reverse shell", + "vmEscape": "VM / hypervisor escape" + }, + "replayTip": "Play every alert of this window in order", + "liveTip": "Follow new alerts as they arrive", + "playAgain": "Play this alert again", + "alertAt": "{{name}} at {{time}}", + "netInternet": "Internet", + "netInternal": "Internal network", + "scUser": "user: {{account}}", + "scWrongPassword": "✕ wrong password", + "scSignedIn": "✓ signed in", + "scSignedInAs": "signed in as {{account}}", + "scFailedSignins": "Failed sign-ins", + "scBlocked": "🛡 {{name}} blocked", + "scSessionAs": "session as {{account}}", + "scHost": "Host · {{name}}", + "scFiles": "Documents", + "scBackups": "Shadow copies", + "scRansomNote": "🔒 RANSOM NOTE", + "scShadows": "✕ shadow copies deleted", + "scPersist": "Persistence", + "scReboot": "survives reboot — backdoor installed", + "scCloud": "External storage", + "scChunk": "data", + "scExfilBytes": "Data exfiltrated", + "scProcessTree": "Process tree", + "scDns": "DNS? {{host}}", + "scThreatIntel": "Threat intel: Alarming (-3)", + "scConnDropped": "✕ connection dropped", + "scPortsProbed": "Ports probed", + "scSignIn": "✓ sign-in", + "scKmInMin": "{{km}} km in {{min}} min", + "scAbroad": "abroad", + "scDropped": "{{status}} dropped", + "scBeacon": "beacon", + "capBrute0": "{{name}}{{sub}} starts guessing passwords against {{where}}.", + "capBruteVpn": "the VPN on {{name}}", + "capBrute1": "{{attempts}} failed sign-ins in {{minutes}} minutes, rotating {{count}} account names.", + "capBrute2": "A sign-in for {{account}} succeeds right after the failures: the password was guessed.", + "capBrute3": "Correlation of the failures across sources: one attacker, many accounts.", + "capBrute4": "Block {{name}} at the edge{{reset}}.", + "capBruteReset": " and reset {{account}}", + "capOut1": "{{who}} looks up {{dest}}.", + "capOut2": "It connects out on port {{port}}{{through}}.", + "capOutThrough": ", through {{name}}", + "capOut3": "Threat intelligence matches {{dest}}: {{kind}}.", + "capOut4": "The connection was dropped, and the alert was raised so the machine gets checked.", + "capOut5": "The connection repeats: {{name}} is likely infected. Isolate it and find the process.", + "capLat0": "{{name}}{{user}} reaches out to {{to}} inside the network.", + "capLatUser": " ({{user}})", + "capLat1": "It authenticates as {{account}} using {{how}}.", + "capLatHowHash": "a stolen password hash", + "capLatHowKerb": "Kerberos service tickets it can crack offline", + "capLatHowAsrep": "a Kerberos reply for an account without pre-authentication", + "capLatHowSmb": "the old SMBv1 protocol", + "capLatHowRdp": "remote sessions and file shares", + "capLat2": "{{to}} accepts the session: the attacker now moves between machines.", + "capLat3": "Disable {{account}} and check both machines.", + "capMal0": "On {{host}}{{user}} runs {{proc}}.", + "capMalUser": ", {{user}}", + "capMal1": "{{p0}} starts {{p1}}: unusual for this program.", + "capMalChild": "a child process", + "capMal2": "{{name}} runs: {{detail}}.", + "capMalKnown": "a known attack technique", + "capMal3": "Stop the process or isolate {{host}}.", + "capWeb0": "{{name}} probes the server on {{to}}.", + "capWeb1": "It sends attack payloads: {{payloads}}…", + "capWeb2": "{{perimeter}} recognizes the attack signatures and drops the requests.", + "capWeb2b": "The IPS recognizes the attack signatures and drops the requests.", + "capWeb3": "Some requests reach {{to}}; the server answers with errors and one 200 OK.", + "capWeb4": "Block {{name}} and check the server's logs.", + "capTrv0": "{{user}} signs in from {{city}}, as usual.", + "capTrv1": "{{gap}} minutes later the same account signs in from {{city}}, {{country}}.", + "capTrvFar": "far away", + "capTrv2": "{{km}} km in {{gap}} minutes: no one travels that fast. The password is likely stolen.", + "capTrv3": "Revoke the sessions and reset {{user}}'s password.", + "capScn0": "{{name}} starts knocking on {{to}}, one port after another.", + "capScn1": "{{count}} ports probed in seconds: SSH, SMB, RDP, databases, web consoles…", + "capScn2": "Ports {{open}} answer; everything else is closed or filtered.", + "capScn3": "Usually the first step of an attack: block the source.", + "capCl0": "{{name}} signs in to {{cloud}}{{from}}.", + "capClFrom": " from {{country}}", + "capClFromDef": "outside the company", + "capCl1": "They change {{what}}.", + "capCl3": "Confirm it was planned, or undo it.", + "capGen0": "{{src}} → {{tgt}}", + "capGen1": "{{what}}", + "capGenNew": "New detection", + "capGen2": "Alert raised: {{name}}.", + "capAlertRaised": "Alert raised: {{name}}. ", + "capBlocked": "{{ip}} is now blocked on {{on}}: the traffic stops here.", + "destUnknown": "unknown destination", + "titleBrute": "Brute force from {{name}} on {{to}}", + "titleOut": "{{name}} contacting {{to}}", + "titleLat": "{{name}} moving to {{to}} as {{account}}", + "titleMal": "{{name}} on {{to}}", + "titleWeb": "Web attack from {{name}} on {{to}}", + "titleTrv": "{{name}} signing in from two continents", + "titleScn": "Port scan from {{name}}", + "titleCl": "{{what}} changed in {{to}}", + "titleAlert": "Alert", + "dLsass": "dumps LSASS memory to steal passwords", + "dMiner": "mines cryptocurrency with the server CPU", + "dRev": "opens an interactive shell back to the attacker", + "dKey": "exports saved passwords from the keychain", + "dTask": "creates a task that runs a payload at every logon", + "dAudit": "wipes the Windows security log", + "dFw": "deletes the host firewall rules", + "dShadow": "deletes the volume shadow copies before encryption", + "dDump": "credential dumping tool", + "dDl": "downloads a tool into a writable folder", + "dPs": "runs an encoded command", + "capRan0": "On {{host}}{{user}}, a process starts touching hundreds of files at once.", + "capRanUser": ", {{user}}", + "capRan1": "Files get renamed with {{exts}}: the data is being encrypted in place.", + "capRan2": "A ransom note is written: the attacker asks for payment to restore the data.", + "capRan2b": "Backups and shadow copies are deleted: no easy way back.", + "capRan3": "Restore from offline backups and find the entry point before the encryption spreads.", + "titleRan": "Ransomware encrypting {{to}}", + "capPer0": "On {{host}}{{user}}, something writes to system startup locations.", + "capPer1": "It drops {{what}}: these run automatically on every boot or logon.", + "capPer2": "Last piece in place: {{what}}. The foothold now survives reboots.", + "capPer3": "Remove the persistence artifacts and hunt for the initial infection vector.", + "titlePer": "Persistence installed on {{to}} via {{what}}", + "dPersistCron": "runs the payload on a schedule", + "dPersistSd": "starts the payload at boot", + "dPersistLaunch": "launches the payload when the user logs in", + "dPersistKey": "lets the attacker SSH back in", + "dPersistRc": "runs the payload in every new shell", + "dPersistPs": "runs the payload in every PowerShell session", + "dPersistPay": "the payload binary itself", + "capExf0": "On {{host}}{{user}}, sensitive data is staged into one archive.", + "capExf1": "It starts transferring out using {{tool}}.", + "capExf2": "The data arrives at {{dest}}: it is now outside the company.", + "capExf3": "Block the transfer, revoke access to {{dest}} and find who can reach that data.", + "titleExf": "{{name}} exfiltrating data to {{to}}", + "scDefenses": "Defenses", + "scDisabled": "✕ disabled", + "scLogsCleared": "🗑 logs cleared", + "dEvLog": "audit trail", + "dEvEnf": "enforcement", + "capEv0": "On {{host}}, the attacker starts reaching for the things that watch it.", + "capEv1": "{{what}} is turned off: one fewer thing that can see them.", + "capEv2": "The logs are wiped: the trail of what they did is gone.", + "capEv2b": "With {{what}} disabled, the host is now blind to the attacker.", + "capEv3": "Restore the disabled tools and preserve the remaining logs before they go too.", + "titleEv": "Defenses disabled on {{to}}", + "scNormalUser": "normal user", + "scToken": "token", + "dEvUac": "UAC bypassed", + "dEvToken": "token impersonated", + "dEvSuid": "setuid binary abused", + "dEvSudo": "sudo caching abused", + "dEvExploit": "kernel exploited", + "dEvDefault": "privilege boundary crossed", + "capPe0": "On {{host}}, the session runs as a normal user.{{user}}", + "capPeUser": ", {{user}}", + "capPe1": "It uses {{method}} to reach a higher privilege level.", + "capPe2": "The commands now run as {{account}}: full control of the host.", + "capPe3": "Terminate the escalated session and audit what {{account}} was able to touch.", + "titlePe": "Privilege escalation to {{to}} via {{method}}", + "alertRaised": "Alert raised", + "userExec": "User opened a malicious file", + "softwareDeploy": "Software pushed to a host", + "phishing": "Phishing email opened", + "processInjection": "Code injected into a process", + "credDump": "Credentials dumped", + "dataDestruction": "Data destroyed", + "toolDownload": "Tool downloaded and executed", + "c2tunnel": "Tunneled command-and-control", + "scExec": "Execution", + "scPayload": "→ malicious payload", + "capUe0": "On {{host}}{{user}}, the user downloads a file and opens it.", + "capUeUser": ", {{user}}", + "capUe1": "The file is opened: {{file}} is trusted and executed.", + "capUe2": "{{app}} starts a child process that runs {{payload}}.", + "capUe3": "Quarantine the file, block its hash and check for other machines that opened it.", + "titleUe": "{{file}} opened on {{to}}", + "scDeploy": "Deployment", + "capSd0": "{{src}} pushes software toward {{to}} over the network.", + "capSd1": "It uses {{tool}}: a channel that installs without user interaction.", + "capSd2": "The package is installed on {{to}} and starts with it.", + "capSd3": "Stop the deployment, remove the installed component and audit what it did.", + "titleSd": "Software deployed from {{src}} to {{to}}", + "scAttachment": "attachment opened", + "capPh0": "{{name}} sends a phishing email into the company.", + "capPh1": "The message lands in {{user}}'s inbox and is opened.", + "capPh2": "The attachment runs: {{file}} executes on the machine.", + "capPh3": "Quarantine the email, block the sender and remove {{file}} from {{user}}'s machine.", + "titlePh": "Phishing email opened by {{user}} (from {{from}})", + "scInject": "Injection", + "scInside": "— code inside a trusted process", + "capPi0": "On {{host}}, the attacker's loader starts: {{injector}}.", + "capPi1": "It injects code into a trusted process: {{victim}}.", + "capPi2": "{{victim}} now runs the attacker's code with its own privileges.", + "capPi3": "Kill the injected code, remove the loader and check for other injection victims.", + "titlePi": "{{injector}} injecting code into {{victim}}", + "scCred": "Credential store", + "scSecrets": "{{n}} secrets", + "scSecret": "secret", + "scStolen": "✕ credentials stolen", + "capCd0": "On {{host}}, a tool starts reading the credential store.", + "capCd1": "It opens {{store}} and extracts the stored material.", + "capCd2": "{{n}} credentials are captured: accounts, keys and hashes.", + "capCd3": "Rotate every credential in the store and hunt for the dumper tool.", + "titleCd": "{{store}} dumped on {{host}}", + "scData": "Data", + "scDataItem": "dataset-{{i}}", + "scGone": "gone", + "scNoRecovery": "data destroyed", + "capDd0": "On {{host}}, something starts erasing data instead of encrypting it.", + "capDd1": "{{n}} datasets are destroyed, one after another.", + "capDd2": "The data is deleted raw: there is no note, no ransom, no way back.", + "capDd3": "Stop the source process and restore what remains from offline backups.", + "titleDd": "Data destroyed on {{host}}", + "scDownload": "bytes", + "scExecuted": "executed", + "capTd0": "{{src}} serves a tool to {{to}}.", + "capTd1": "It is downloaded into a writable folder: {{folder}}.", + "capTd2": "The file is executed: {{tool}} is now running.", + "capTd3": "Delete the tool, block its hash and check which hosts ran it.", + "titleTd": "{{src}} drops a tool on {{to}}", + "scTunnel": "hidden in {{proto}} traffic", + "scTunneled": "Bytes tunneled", + "capCt0": "{{src}} talks to {{to}} using a normal-looking protocol.", + "capCt1": "The payload is hidden inside {{proto}} traffic.", + "capCt2": "Commands and data cross the boundary unseen, riding {{proto}}.", + "capCt3": "Cut the tunnel, block the endpoint and check what went through it.", + "titleCt": "{{src}} tunneling C2 through {{proto}} to {{to}}", + "netPerimeter": "Perimeter", + "scDc": "Domain controller", + "scObject": "Changed object", + "scChangedBy": "changed by", + "scHighRisk": "high-risk change", + "scTktAsk": "ticket request", + "scTktUses": "reused on {{n}} services", + "scTerminal": "Terminal", + "scRunning": "…running", + "scAmsiOff": "⚠ AMSI disabled", + "scConn": "TCP {{port}}", + "scShellOn": "$ reverse shell", + "scHypervisor": "Hypervisor", + "scGuestVm": "guest virtual machine", + "scConfined": "confined to guest", + "scEscaped": "escaped to host", + "scBoundary": "guest boundary crossed", + "scFeedAsk": "feed? {{ioc}}", + "scFeedBad": "BAD", + "scFeedHit": "Threat intel: {{kind}}", + "scDroppedAtFw": "✕ dropped at {{fw}}", + "scTrafficStops": "traffic stops here", + "scSigHits": "Signature hits", + "capIoc0": "{{src}} connects to {{ioc}}.", + "capIoc1": "Threat intelligence flags it: {{kind}}.", + "capIoc2": "{{ioc}} is on the block list: the connection is cut.", + "capIoc3": "Block {{ioc}} at the edge and check what already left the network.", + "titleIoc": "{{src}} reaches a known-bad {{ioc}}", + "capPd0": "{{name}} sends a {{sig}} at the perimeter.", + "capPd1": "{{fw}} matches the signature and fires.", + "capPd2": "The traffic is dropped: the perimeter held.", + "capPd3": "The traffic crosses {{fw}}: the alert is informational.", + "capPd4": "Review the signature and block the source if it keeps coming.", + "titlePd": "{{sig}} blocked at {{fw}}", + "capAc0": "{{who}} changes {{what}} on {{host}}.", + "capAc1": "The {{what}} is modified.", + "capAc2": "{{before}} → {{after}}.", + "capAc3": "Confirm it was planned, or revert the change made by {{who}}.", + "titleAc": "{{what}} changed on {{host}}", + "capKb0": "{{src}} asks {{dc}} for Kerberos tickets.", + "capKb1": "The {{ticket}} it gets is {{kind}}.", + "capKb2": "It reuses the ticket on {{services}}: the DC accepts it each time.", + "capKb3": "Reset the krbtgt password and audit the tickets issued in the last 48 h.", + "titleKb": "{{src}} forging Kerberos tickets via {{dc}}", + "capPs0": "On {{host}}, a script starts with encoded content.", + "capPs1": "It decodes a command and disables the anti-malware sensor (AMSI).", + "capPs2": "The decoded command executes: this is a payload, not a script.", + "capPs2a": "AMSI is disabled first, then the encoded command runs unseen.", + "capPs3": "Block the hash, hunt for other machines with the same script.", + "titlePs2": "Encoded script executing on {{host}}", + "capRs0": "On {{host}}, a process opens a socket to the outside.", + "capRs1": "It connects back to {{name}} on port {{port}}: a reverse shell.", + "capRs2": "A prompt appears: the attacker can now type commands on the host.", + "capRs3": "Kill the connection, isolate {{host}} and find what was typed.", + "titleRs": "Reverse shell opened on {{host}}", + "capVm0": "The guest VM {{guest}} runs a process with host-level access.", + "capVm1": "It tries to cross the hypervisor boundary.", + "capVm2": "The process runs on the {{host}} host: the guest is no longer a cage.", + "capVm3": "Panic the hypervisor, snapshot the guest and rebuild it.", + "titleVm": "Guest {{guest}} escaping to {{host}}", + "listNew": "New", + "newAlertsCount_one": "{{count}} new alert", + "newAlertsCount_other": "{{count}} new alerts", + "statTotal": "Total", + "timPage": "Page {{p}}/{{n}}", + "timPagePrev": "Previous page", + "timPageNext": "Next page", + "newAlerts": "New alerts" }, - "replayTip": "Play every alert of this window in order", - "liveTip": "Follow new alerts as they arrive", - "playAgain": "Play this alert again", - "alertAt": "{{name}} at {{time}}", - "netInternet": "Internet", - "netInternal": "Internal network", - "scUser": "user: {{account}}", - "scWrongPassword": "✕ wrong password", - "scSignedIn": "✓ signed in", - "scSignedInAs": "signed in as {{account}}", - "scFailedSignins": "Failed sign-ins", - "scBlocked": "🛡 {{name}} blocked", - "scSessionAs": "session as {{account}}", - "scHost": "Host · {{name}}", - "scFiles": "Documents", - "scBackups": "Shadow copies", - "scRansomNote": "🔒 RANSOM NOTE", - "scShadows": "✕ shadow copies deleted", - "scPersist": "Persistence", - "scReboot": "survives reboot — backdoor installed", - "scCloud": "External storage", - "scChunk": "data", - "scExfilBytes": "Data exfiltrated", - "scProcessTree": "Process tree", - "scDns": "DNS? {{host}}", - "scThreatIntel": "Threat intel: Alarming (-3)", - "scConnDropped": "✕ connection dropped", - "scPortsProbed": "Ports probed", - "scSignIn": "✓ sign-in", - "scKmInMin": "{{km}} km in {{min}} min", - "scAbroad": "abroad", - "scDropped": "{{status}} dropped", - "scBeacon": "beacon", - "capBrute0": "{{name}}{{sub}} starts guessing passwords against {{where}}.", - "capBruteVpn": "the VPN on {{name}}", - "capBrute1": "{{attempts}} failed sign-ins in {{minutes}} minutes, rotating {{count}} account names.", - "capBrute2": "A sign-in for {{account}} succeeds right after the failures: the password was guessed.", - "capBrute3": "Correlation of the failures across sources: one attacker, many accounts.", - "capBrute4": "Block {{name}} at the edge{{reset}}.", - "capBruteReset": " and reset {{account}}", - "capOut1": "{{who}} looks up {{dest}}.", - "capOut2": "It connects out on port {{port}}{{through}}.", - "capOutThrough": ", through {{name}}", - "capOut3": "Threat intelligence matches {{dest}}: {{kind}}.", - "capOut4": "The connection was dropped, and the alert was raised so the machine gets checked.", - "capOut5": "The connection repeats: {{name}} is likely infected. Isolate it and find the process.", - "capLat0": "{{name}}{{user}} reaches out to {{to}} inside the network.", - "capLatUser": " ({{user}})", - "capLat1": "It authenticates as {{account}} using {{how}}.", - "capLatHowHash": "a stolen password hash", - "capLatHowKerb": "Kerberos service tickets it can crack offline", - "capLatHowAsrep": "a Kerberos reply for an account without pre-authentication", - "capLatHowSmb": "the old SMBv1 protocol", - "capLatHowRdp": "remote sessions and file shares", - "capLat2": "{{to}} accepts the session: the attacker now moves between machines.", - "capLat3": "Disable {{account}} and check both machines.", - "capMal0": "On {{host}}{{user}} runs {{proc}}.", - "capMalUser": ", {{user}}", - "capMal1": "{{p0}} starts {{p1}}: unusual for this program.", - "capMalChild": "a child process", - "capMal2": "{{name}} runs: {{detail}}.", - "capMalKnown": "a known attack technique", - "capMal3": "Stop the process or isolate {{host}}.", - "capWeb0": "{{name}} probes the server on {{to}}.", - "capWeb1": "It sends attack payloads: {{payloads}}…", - "capWeb2": "{{perimeter}} recognizes the attack signatures and drops the requests.", - "capWeb2b": "The IPS recognizes the attack signatures and drops the requests.", - "capWeb3": "Some requests reach {{to}}; the server answers with errors and one 200 OK.", - "capWeb4": "Block {{name}} and check the server's logs.", - "capTrv0": "{{user}} signs in from {{city}}, as usual.", - "capTrv1": "{{gap}} minutes later the same account signs in from {{city}}, {{country}}.", - "capTrvFar": "far away", - "capTrv2": "{{km}} km in {{gap}} minutes: no one travels that fast. The password is likely stolen.", - "capTrv3": "Revoke the sessions and reset {{user}}'s password.", - "capScn0": "{{name}} starts knocking on {{to}}, one port after another.", - "capScn1": "{{count}} ports probed in seconds: SSH, SMB, RDP, databases, web consoles…", - "capScn2": "Ports {{open}} answer; everything else is closed or filtered.", - "capScn3": "Usually the first step of an attack: block the source.", - "capCl0": "{{name}} signs in to {{cloud}}{{from}}.", - "capClFrom": " from {{country}}", - "capClFromDef": "outside the company", - "capCl1": "They change {{what}}.", - "capCl3": "Confirm it was planned, or undo it.", - "capGen0": "{{src}} → {{tgt}}", - "capGen1": "{{what}}", - "capGenNew": "New detection", - "capGen2": "Alert raised: {{name}}.", - "capAlertRaised": "Alert raised: {{name}}. ", - "capBlocked": "{{ip}} is now blocked on {{on}}: the traffic stops here.", - "destUnknown": "unknown destination", - "titleBrute": "Brute force from {{name}} on {{to}}", - "titleOut": "{{name}} contacting {{to}}", - "titleLat": "{{name}} moving to {{to}} as {{account}}", - "titleMal": "{{name}} on {{to}}", - "titleWeb": "Web attack from {{name}} on {{to}}", - "titleTrv": "{{name}} signing in from two continents", - "titleScn": "Port scan from {{name}}", - "titleCl": "{{what}} changed in {{to}}", - "titleAlert": "Alert", - "dLsass": "dumps LSASS memory to steal passwords", - "dMiner": "mines cryptocurrency with the server CPU", - "dRev": "opens an interactive shell back to the attacker", - "dKey": "exports saved passwords from the keychain", - "dTask": "creates a task that runs a payload at every logon", - "dAudit": "wipes the Windows security log", - "dFw": "deletes the host firewall rules", - "dShadow": "deletes the volume shadow copies before encryption", - "dDump": "credential dumping tool", - "dDl": "downloads a tool into a writable folder", - "dPs": "runs an encoded command", - "capRan0": "On {{host}}{{user}}, a process starts touching hundreds of files at once.", - "capRanUser": ", {{user}}", - "capRan1": "Files get renamed with {{exts}}: the data is being encrypted in place.", - "capRan2": "A ransom note is written: the attacker asks for payment to restore the data.", - "capRan2b": "Backups and shadow copies are deleted: no easy way back.", - "capRan3": "Restore from offline backups and find the entry point before the encryption spreads.", - "titleRan": "Ransomware encrypting {{to}}", - "capPer0": "On {{host}}{{user}}, something writes to system startup locations.", - "capPer1": "It drops {{what}}: these run automatically on every boot or logon.", - "capPer2": "Last piece in place: {{what}}. The foothold now survives reboots.", - "capPer3": "Remove the persistence artifacts and hunt for the initial infection vector.", - "titlePer": "Persistence installed on {{to}} via {{what}}", - "dPersistCron": "runs the payload on a schedule", - "dPersistSd": "starts the payload at boot", - "dPersistLaunch": "launches the payload when the user logs in", - "dPersistKey": "lets the attacker SSH back in", - "dPersistRc": "runs the payload in every new shell", - "dPersistPs": "runs the payload in every PowerShell session", - "dPersistPay": "the payload binary itself", - "capExf0": "On {{host}}{{user}}, sensitive data is staged into one archive.", - "capExf1": "It starts transferring out using {{tool}}.", - "capExf2": "The data arrives at {{dest}}: it is now outside the company.", - "capExf3": "Block the transfer, revoke access to {{dest}} and find who can reach that data.", - "titleExf": "{{name}} exfiltrating data to {{to}}", - "scDefenses": "Defenses", - "scDisabled": "✕ disabled", - "scLogsCleared": "🗑 logs cleared", - "dEvLog": "audit trail", - "dEvEnf": "enforcement", - "capEv0": "On {{host}}, the attacker starts reaching for the things that watch it.", - "capEv1": "{{what}} is turned off: one fewer thing that can see them.", - "capEv2": "The logs are wiped: the trail of what they did is gone.", - "capEv2b": "With {{what}} disabled, the host is now blind to the attacker.", - "capEv3": "Restore the disabled tools and preserve the remaining logs before they go too.", - "titleEv": "Defenses disabled on {{to}}", - "scNormalUser": "normal user", - "scToken": "token", - "dEvUac": "UAC bypassed", - "dEvToken": "token impersonated", - "dEvSuid": "setuid binary abused", - "dEvSudo": "sudo caching abused", - "dEvExploit": "kernel exploited", - "dEvDefault": "privilege boundary crossed", - "capPe0": "On {{host}}, the session runs as a normal user.{{user}}", - "capPeUser": ", {{user}}", - "capPe1": "It uses {{method}} to reach a higher privilege level.", - "capPe2": "The commands now run as {{account}}: full control of the host.", - "capPe3": "Terminate the escalated session and audit what {{account}} was able to touch.", - "titlePe": "Privilege escalation to {{to}} via {{method}}", - "alertRaised": "Alert raised", - "userExec": "User opened a malicious file", - "softwareDeploy": "Software pushed to a host", - "phishing": "Phishing email opened", - "processInjection": "Code injected into a process", - "credDump": "Credentials dumped", - "dataDestruction": "Data destroyed", - "toolDownload": "Tool downloaded and executed", - "c2tunnel": "Tunneled command-and-control", "scExec": "Execution", "scPayload": "→ malicious payload", "capUe0": "On {{host}}{{user}}, the user downloads a file and opens it.", @@ -6512,133 +6664,5 @@ "capCt1": "The payload is hidden inside {{proto}} traffic.", "capCt2": "Commands and data cross the boundary unseen, riding {{proto}}.", "capCt3": "Cut the tunnel, block the endpoint and check what went through it.", - "titleCt": "{{src}} tunneling C2 through {{proto}} to {{to}}", - "netPerimeter": "Perimeter", - "scDc": "Domain controller", - "scObject": "Changed object", - "scChangedBy": "changed by", - "scHighRisk": "high-risk change", - "scTktAsk": "ticket request", - "scTktUses": "reused on {{n}} services", - "scTerminal": "Terminal", - "scRunning": "…running", - "scAmsiOff": "⚠ AMSI disabled", - "scConn": "TCP {{port}}", - "scShellOn": "$ reverse shell", - "scHypervisor": "Hypervisor", - "scGuestVm": "guest virtual machine", - "scConfined": "confined to guest", - "scEscaped": "escaped to host", - "scBoundary": "guest boundary crossed", - "scFeedAsk": "feed? {{ioc}}", - "scFeedBad": "BAD", - "scFeedHit": "Threat intel: {{kind}}", - "scDroppedAtFw": "✕ dropped at {{fw}}", - "scTrafficStops": "traffic stops here", - "scSigHits": "Signature hits", - "capIoc0": "{{src}} connects to {{ioc}}.", - "capIoc1": "Threat intelligence flags it: {{kind}}.", - "capIoc2": "{{ioc}} is on the block list: the connection is cut.", - "capIoc3": "Block {{ioc}} at the edge and check what already left the network.", - "titleIoc": "{{src}} reaches a known-bad {{ioc}}", - "capPd0": "{{name}} sends a {{sig}} at the perimeter.", - "capPd1": "{{fw}} matches the signature and fires.", - "capPd2": "The traffic is dropped: the perimeter held.", - "capPd3": "The traffic crosses {{fw}}: the alert is informational.", - "capPd4": "Review the signature and block the source if it keeps coming.", - "titlePd": "{{sig}} blocked at {{fw}}", - "capAc0": "{{who}} changes {{what}} on {{host}}.", - "capAc1": "The {{what}} is modified.", - "capAc2": "{{before}} → {{after}}.", - "capAc3": "Confirm it was planned, or revert the change made by {{who}}.", - "titleAc": "{{what}} changed on {{host}}", - "capKb0": "{{src}} asks {{dc}} for Kerberos tickets.", - "capKb1": "The {{ticket}} it gets is {{kind}}.", - "capKb2": "It reuses the ticket on {{services}}: the DC accepts it each time.", - "capKb3": "Reset the krbtgt password and audit the tickets issued in the last 48 h.", - "titleKb": "{{src}} forging Kerberos tickets via {{dc}}", - "capPs0": "On {{host}}, a script starts with encoded content.", - "capPs1": "It decodes a command and disables the anti-malware sensor (AMSI).", - "capPs2": "The decoded command executes: this is a payload, not a script.", - "capPs2a": "AMSI is disabled first, then the encoded command runs unseen.", - "capPs3": "Block the hash, hunt for other machines with the same script.", - "titlePs2": "Encoded script executing on {{host}}", - "capRs0": "On {{host}}, a process opens a socket to the outside.", - "capRs1": "It connects back to {{name}} on port {{port}}: a reverse shell.", - "capRs2": "A prompt appears: the attacker can now type commands on the host.", - "capRs3": "Kill the connection, isolate {{host}} and find what was typed.", - "titleRs": "Reverse shell opened on {{host}}", - "capVm0": "The guest VM {{guest}} runs a process with host-level access.", - "capVm1": "It tries to cross the hypervisor boundary.", - "capVm2": "The process runs on the {{host}} host: the guest is no longer a cage.", - "capVm3": "Panic the hypervisor, snapshot the guest and rebuild it.", - "titleVm": "Guest {{guest}} escaping to {{host}}", - "listNew": "New", - "newAlertsCount_one": "{{count}} new alert", - "newAlertsCount_other": "{{count}} new alerts", - "statTotal": "Total", - "timPage": "Page {{p}}/{{n}}", - "timPagePrev": "Previous page", - "timPageNext": "Next page", - "newAlerts": "New alerts" - }, - "scExec": "Execution", - "scPayload": "→ malicious payload", - "capUe0": "On {{host}}{{user}}, the user downloads a file and opens it.", - "capUeUser": ", {{user}}", - "capUe1": "The file is opened: {{file}} is trusted and executed.", - "capUe2": "{{app}} starts a child process that runs {{payload}}.", - "capUe3": "Quarantine the file, block its hash and check for other machines that opened it.", - "titleUe": "{{file}} opened on {{to}}", - "scDeploy": "Deployment", - "capSd0": "{{src}} pushes software toward {{to}} over the network.", - "capSd1": "It uses {{tool}}: a channel that installs without user interaction.", - "capSd2": "The package is installed on {{to}} and starts with it.", - "capSd3": "Stop the deployment, remove the installed component and audit what it did.", - "titleSd": "Software deployed from {{src}} to {{to}}", - "scAttachment": "attachment opened", - "capPh0": "{{name}} sends a phishing email into the company.", - "capPh1": "The message lands in {{user}}'s inbox and is opened.", - "capPh2": "The attachment runs: {{file}} executes on the machine.", - "capPh3": "Quarantine the email, block the sender and remove {{file}} from {{user}}'s machine.", - "titlePh": "Phishing email opened by {{user}} (from {{from}})", - "scInject": "Injection", - "scInside": "— code inside a trusted process", - "capPi0": "On {{host}}, the attacker's loader starts: {{injector}}.", - "capPi1": "It injects code into a trusted process: {{victim}}.", - "capPi2": "{{victim}} now runs the attacker's code with its own privileges.", - "capPi3": "Kill the injected code, remove the loader and check for other injection victims.", - "titlePi": "{{injector}} injecting code into {{victim}}", - "scCred": "Credential store", - "scSecrets": "{{n}} secrets", - "scSecret": "secret", - "scStolen": "✕ credentials stolen", - "capCd0": "On {{host}}, a tool starts reading the credential store.", - "capCd1": "It opens {{store}} and extracts the stored material.", - "capCd2": "{{n}} credentials are captured: accounts, keys and hashes.", - "capCd3": "Rotate every credential in the store and hunt for the dumper tool.", - "titleCd": "{{store}} dumped on {{host}}", - "scData": "Data", - "scDataItem": "dataset-{{i}}", - "scGone": "gone", - "scNoRecovery": "data destroyed", - "capDd0": "On {{host}}, something starts erasing data instead of encrypting it.", - "capDd1": "{{n}} datasets are destroyed, one after another.", - "capDd2": "The data is deleted raw: there is no note, no ransom, no way back.", - "capDd3": "Stop the source process and restore what remains from offline backups.", - "titleDd": "Data destroyed on {{host}}", - "scDownload": "bytes", - "scExecuted": "executed", - "capTd0": "{{src}} serves a tool to {{to}}.", - "capTd1": "It is downloaded into a writable folder: {{folder}}.", - "capTd2": "The file is executed: {{tool}} is now running.", - "capTd3": "Delete the tool, block its hash and check which hosts ran it.", - "titleTd": "{{src}} drops a tool on {{to}}", - "scTunnel": "hidden in {{proto}} traffic", - "scTunneled": "Bytes tunneled", - "capCt0": "{{src}} talks to {{to}} using a normal-looking protocol.", - "capCt1": "The payload is hidden inside {{proto}} traffic.", - "capCt2": "Commands and data cross the boundary unseen, riding {{proto}}.", - "capCt3": "Cut the tunnel, block the endpoint and check what went through it.", - "titleCt": "{{src}} tunneling C2 through {{proto}} to {{to}}" + "titleCt": "{{src}} tunneling C2 through {{proto}} to {{to}}" } diff --git a/frontend/src/shared/i18n/locales/es.json b/frontend/src/shared/i18n/locales/es.json index 7fabba39b..23725085b 100644 --- a/frontend/src/shared/i18n/locales/es.json +++ b/frontend/src/shared/i18n/locales/es.json @@ -1,6459 +1,6611 @@ { - "onboarding": { - "adminEmail": { - "title": "Configura el email del administrador", - "subtitle": "Requerido antes de continuar", - "description": "Tu cuenta de administrador todavía usa el email por defecto. Pon una dirección real — se necesita para recuperar la contraseña, las notificaciones y los correos de alertas.", - "emailLabel": "Correo electrónico", - "save": "Guardar y continuar", - "saving": "Guardando…", - "success": "Email del administrador configurado. Ahora configura tu servidor de correo.", - "error": "No se pudo guardar tu email. Inténtalo de nuevo." - } - }, - "common": { - "appName": "UTMStack", - "language": "Idioma", - "actions": { - "save": "Guardar", - "cancel": "Cancelar", - "retry": "Reintentar", - "refresh": "Actualizar", - "delete": "Eliminar", - "remove": "Quitar", - "close": "Cerrar", - "next": "Siguiente", - "back": "Atrás" - }, - "confirm": { - "delete": "Eliminar", - "working": "Procesando…" - }, - "dateRange": { - "pick": "Elegir un rango", - "clear": "Limpiar", - "done": "Listo", - "apply": "Aplicar" - }, - "loadingMore": "Cargando más…", - "allLoaded": "Cargados los {{count}}", - "startFrom": { - "scratch": "Desde cero", - "scratchHint": "Una definición vacía que rellenas tú.", - "copy": "Desde una existente", - "copyHint": "Se copia todo salvo el identificador y el nombre.", - "pickTitle": "Elige cuál copiar", - "back": "Volver", - "count": "{{n}} disponibles", - "search": "Buscar por nombre", - "none": "Nada coincide con esa búsqueda" - }, - "cancel": "Cancelar" - }, - "auth": { - "login": { - "title": "Bienvenido de nuevo", - "subtitle": "Inicia sesión para continuar en {{brand}}", - "loginLabel": "Correo electrónico", - "passwordLabel": "Contraseña", - "forgot": "¿Olvidaste?", - "submit": "Iniciar sesión", - "terms": "Al iniciar sesión, aceptas los términos de servicio de {{brand}}.", - "orContinueWith": "o continúa con", - "continueWith": "Continuar con {{name}}", - "signingInTo": "Entrando en {{name}}", - "useAnother": "Usar otro" - }, - "tfa": { - "title": "Verificación en dos pasos", - "subtitleTotp": "Ingresa el código de 6 dígitos de tu app de autenticación.", - "subtitleEmail": "Ingresa el código de 6 dígitos que te enviamos por correo.", - "codeLabel": "Código de verificación", - "submit": "Verificar", - "back": "Volver a iniciar sesión" + "onboarding": { + "adminEmail": { + "title": "Configura el email del administrador", + "subtitle": "Requerido antes de continuar", + "description": "Tu cuenta de administrador todavía usa el email por defecto. Pon una dirección real — se necesita para recuperar la contraseña, las notificaciones y los correos de alertas.", + "emailLabel": "Correo electrónico", + "save": "Guardar y continuar", + "saving": "Guardando…", + "success": "Email del administrador configurado. Ahora configura tu servidor de correo.", + "error": "No se pudo guardar tu email. Inténtalo de nuevo." + } }, - "forgot": { - "title": "Restablecer contraseña", - "subtitle": "Te enviaremos un enlace por correo para establecer una nueva contraseña.", - "emailLabel": "Correo", - "submit": "Enviar enlace", - "sent": "Si ese correo está registrado, el enlace de restablecimiento va en camino." + "common": { + "appName": "UTMStack", + "language": "Idioma", + "actions": { + "save": "Guardar", + "cancel": "Cancelar", + "retry": "Reintentar", + "refresh": "Actualizar", + "delete": "Eliminar", + "remove": "Quitar", + "close": "Cerrar", + "next": "Siguiente", + "back": "Atrás" + }, + "confirm": { + "delete": "Eliminar", + "working": "Procesando…" + }, + "dateRange": { + "pick": "Elegir un rango", + "clear": "Limpiar", + "done": "Listo", + "apply": "Aplicar" + }, + "loadingMore": "Cargando más…", + "allLoaded": "Cargados los {{count}}", + "startFrom": { + "scratch": "Desde cero", + "scratchHint": "Una definición vacía que rellenas tú.", + "copy": "Desde una existente", + "copyHint": "Se copia todo salvo el identificador y el nombre.", + "pickTitle": "Elige cuál copiar", + "back": "Volver", + "count": "{{n}} disponibles", + "search": "Buscar por nombre", + "none": "Nada coincide con esa búsqueda" + }, + "cancel": "Cancelar" + }, + "auth": { + "login": { + "title": "Bienvenido de nuevo", + "subtitle": "Inicia sesión para continuar en {{brand}}", + "loginLabel": "Correo electrónico", + "passwordLabel": "Contraseña", + "forgot": "¿Olvidaste?", + "submit": "Iniciar sesión", + "terms": "Al iniciar sesión, aceptas los términos de servicio de {{brand}}.", + "orContinueWith": "o continúa con", + "continueWith": "Continuar con {{name}}", + "signingInTo": "Entrando en {{name}}", + "useAnother": "Usar otro" + }, + "tfa": { + "title": "Verificación en dos pasos", + "subtitleTotp": "Ingresa el código de 6 dígitos de tu app de autenticación.", + "subtitleEmail": "Ingresa el código de 6 dígitos que te enviamos por correo.", + "codeLabel": "Código de verificación", + "submit": "Verificar", + "back": "Volver a iniciar sesión" + }, + "forgot": { + "title": "Restablecer contraseña", + "subtitle": "Te enviaremos un enlace por correo para establecer una nueva contraseña.", + "emailLabel": "Correo", + "submit": "Enviar enlace", + "sent": "Si ese correo está registrado, el enlace de restablecimiento va en camino." + }, + "errors": { + "tooManyAttempts": "Demasiados intentos. Vuelve a intentarlo en unos minutos.", + "deactivated": "Esta cuenta está desactivada.", + "invalidCredentials": "Credenciales inválidas.", + "codeExpired": "Este código expiró. Inicia sesión de nuevo.", + "loginFailed": "Error al iniciar sesión. Inténtalo de nuevo.", + "invalidCode": "Código inválido o expirado.", + "verifyFailed": "La verificación falló. Inténtalo de nuevo.", + "resetFailed": "No se pudo enviar el correo de restablecimiento. Inténtalo de nuevo.", + "ssoFailed": "El inicio de sesión único no se completó. Inténtalo de nuevo o usa tu contraseña." + } }, - "errors": { - "tooManyAttempts": "Demasiados intentos. Vuelve a intentarlo en unos minutos.", - "deactivated": "Esta cuenta está desactivada.", - "invalidCredentials": "Credenciales inválidas.", - "codeExpired": "Este código expiró. Inicia sesión de nuevo.", - "loginFailed": "Error al iniciar sesión. Inténtalo de nuevo.", - "invalidCode": "Código inválido o expirado.", - "verifyFailed": "La verificación falló. Inténtalo de nuevo.", - "resetFailed": "No se pudo enviar el correo de restablecimiento. Inténtalo de nuevo.", - "ssoFailed": "El inicio de sesión único no se completó. Inténtalo de nuevo o usa tu contraseña." - } - }, - "profile": { - "hero": { - "administrator": "Administrador", - "changeAvatar": "Cambiar avatar", - "removeAvatar": "Quitar avatar" + "profile": { + "hero": { + "administrator": "Administrador", + "changeAvatar": "Cambiar avatar", + "removeAvatar": "Quitar avatar" + }, + "personal": { + "title": "Información personal", + "description": "Actualiza tu nombre y datos de contacto.", + "firstName": "Nombre", + "lastName": "Apellido", + "email": "Correo", + "language": "Idioma", + "languageHint": "Usado para la interfaz del panel.", + "systemDefault": "Predeterminado del sistema", + "username": "Usuario", + "usernameHint": "El usuario no se puede cambiar.", + "reset": "Restablecer", + "save": "Guardar cambios", + "saving": "Guardando…", + "name": "Nombre" + }, + "password": { + "title": "Contraseña", + "description": "Usa una contraseña fuerte que no reutilices en ningún otro sitio.", + "current": "Contraseña actual", + "new": "Nueva contraseña", + "newHint": "Al menos 8 caracteres.", + "confirm": "Confirmar nueva contraseña", + "update": "Actualizar contraseña", + "updating": "Actualizando…" + }, + "sessions": { + "title": "Sesiones activas", + "description": "Dispositivos con sesión iniciada en tu cuenta.", + "loading": "Cargando sesiones…", + "empty": "No hay sesiones activas.", + "thisDevice": "Este dispositivo", + "unknownIp": "IP desconocida", + "unknownDevice": "Dispositivo desconocido", + "deviceLabel": "{{browser}} en {{os}}", + "signedIn": "Inició sesión {{time}}", + "revoke": "Revocar", + "revoking": "Revocando…", + "signOutOthers": "Cerrar todas las demás sesiones", + "signingOut": "Cerrando…" + }, + "tfa": { + "title": "Autenticación en dos pasos", + "description": "Agrega una capa extra de seguridad a tu cuenta.", + "loading": "Cargando…", + "methodTotp": "App de autenticación", + "methodEmail": "Código por correo", + "onTitle": "La autenticación en dos pasos está activada", + "method": "Método: {{method}}", + "configured": "Configurado", + "disable": "Desactivar", + "disableTitle": "Desactivar autenticación en dos pasos", + "disableDescription": "Ingresa tu contraseña actual para confirmar. Tu cuenta dependerá solo de la contraseña después.", + "currentPasswordPlaceholder": "Contraseña actual", + "disableConfirm": "Desactivar 2FA", + "disabling": "Desactivando…", + "offTitle": "La autenticación en dos pasos está desactivada", + "status": "Estado:", + "notConfigured": "Sin configurar", + "enable": "Activar", + "chooseMethod": "Elige un método", + "totpDesc": "Usa Google Authenticator, 1Password, etc. Recomendado.", + "emailDesc": "Recibe un código de 6 dígitos por correo al iniciar sesión.", + "noEmailHint": "Agrega un correo a tu perfil para usar el método por correo.", + "continue": "Continuar", + "starting": "Iniciando…", + "scanTitle": "Escanea el código QR", + "scanDescription": "Escanéalo con tu app de autenticación y luego ingresa el código de 6 dígitos que muestra.", + "manualKey": "O ingresa esta clave manualmente:", + "checkEmailTitle": "Revisa tu correo", + "checkEmailDescription": "Enviamos un código de 6 dígitos a {{email}}. Ingrésalo abajo.", + "resend": "Reenviar", + "verifyEnable": "Verificar y activar", + "verifying": "Verificando…" + }, + "actions": { + "cancel": "Cancelar" + }, + "toast": { + "profileUpdated": "Perfil actualizado", + "emailInUse": "Ese correo ya está en uso", + "profileUpdateFailed": "No se pudo actualizar el perfil", + "passwordsNoMatch": "Las contraseñas no coinciden", + "passwordTooShort": "La contraseña debe tener al menos 8 caracteres", + "passwordChanged": "Contraseña cambiada — se cerraron las demás sesiones", + "currentPasswordWrong": "La contraseña actual es incorrecta", + "passwordChangeFailed": "No se pudo cambiar la contraseña", + "avatarTypeNotAllowed": "Tipo de imagen no permitido (usa PNG, JPEG, WEBP o GIF)", + "avatarTooLarge": "La imagen es demasiado grande (máx. 2MB)", + "avatarUpdated": "Avatar actualizado", + "avatarUploadFailed": "No se pudo subir el avatar", + "avatarRemoved": "Avatar eliminado", + "avatarRemoveFailed": "No se pudo eliminar el avatar", + "sessionsLoadFailed": "No se pudieron cargar las sesiones", + "sessionRevoked": "Sesión revocada", + "sessionRevokeFailed": "No se pudo revocar la sesión", + "othersSignedOut": "Se cerraron las demás sesiones", + "othersRevokeFailed": "No se pudieron revocar las sesiones", + "tfaEmailCodeSent": "Enviamos un código de 6 dígitos a tu correo", + "tfaNewCodeSent": "Se envió un nuevo código", + "tfaWaitResend": "Espera un momento antes de pedir un nuevo código", + "tfaResendFailed": "No se pudo reenviar el código", + "tfaEnterCode": "Ingresa el código de 6 dígitos", + "tfaEnabled": "Autenticación en dos pasos activada", + "tfaEnterPassword": "Ingresa tu contraseña actual", + "tfaDisabled": "Autenticación en dos pasos desactivada", + "tfaDisableFailed": "No se pudo desactivar 2FA", + "tfaInvalidCode": "Código inválido o expirado", + "tfaAlreadyEnabled": "2FA ya está activado", + "tfaTooManyRequests": "Demasiadas solicitudes; inténtalo en un momento", + "tfaVerifyFailed": "No se pudo verificar el código", + "genericError": "Algo salió mal", + "tfaMailUnavailable": "El segundo factor por correo necesita un servidor de correo. Configúralo en Ajustes → Configuración de correo." + } }, - "personal": { - "title": "Información personal", - "description": "Actualiza tu nombre y datos de contacto.", - "firstName": "Nombre", - "lastName": "Apellido", - "email": "Correo", - "language": "Idioma", - "languageHint": "Usado para la interfaz del panel.", - "systemDefault": "Predeterminado del sistema", - "username": "Usuario", - "usernameHint": "El usuario no se puede cambiar.", - "reset": "Restablecer", - "save": "Guardar cambios", - "saving": "Guardando…", - "name": "Nombre" + "home": { + "hero": { + "title": "¿Qué te gustaría saber a partir de tus datos de seguridad?", + "placeholder": "Investiga a Scattered Spider, ¿nos aplica?, ¿nos han atacado alguna vez?, crea una regla de detección y mantenla ajustada.", + "send": "Enviar", + "suggestions": { + "threatHunt": "Caza de amenazas", + "observableTriage": "Triaje de observables", + "writeRule": "Escribir una regla", + "systemStatus": "Estado actual del sistema" + } + }, + "kpis": { + "alerts24h": "Alertas (24 h)", + "openIncidents": "Incidentes abiertos", + "openIncidentsSub": "abiertos actualmente", + "highSeverity24h": "Severidad alta (24 h)", + "highSeveritySub": "de {{n}} alertas", + "activePlaybooks": "Playbooks activos", + "activePlaybooksSub": "habilitados" + }, + "datasources": { + "title": "Fuentes de datos", + "viewAll": "Ver todo", + "ofTotal": "de {{n}}", + "datasources": "fuentes de datos", + "sendingData": "enviando datos", + "totalEvents": "Eventos totales", + "noData": "Sin datos de ingesta en esta ventana" + }, + "span": { + "recent": "ventana reciente", + "days_one": "último {{count}} día", + "days_other": "últimos {{count}} días", + "hours": "últimas {{n}} h" + }, + "mitre": { + "title": "Técnicas MITRE ATT&CK principales", + "explore": "Explorar", + "empty": "Aún no hay alertas con técnica asignada" + }, + "assets": { + "title": "Activos más atacados", + "viewAll": "Ver todo", + "asset": "Activo", + "alerts": "Alertas", + "empty": "No hay activos atacados en las alertas recientes" + }, + "compliance": { + "title": "Puntuación de cumplimiento", + "reports": "Informes", + "empty": "Aún no se han generado informes de cumplimiento" + }, + "health": { + "title": "Estado del sistema", + "details": "Detalles", + "services": { + "backend": "API del backend", + "opensearch": "Clúster de OpenSearch", + "socai": "Motor SOC-AI" + }, + "detail": { + "noClusterInfo": "sin información del clúster", + "disabled": "deshabilitado", + "tools": "{{n}} herramientas", + "unreachable": "inaccesible", + "pending": "…" + } + } }, - "password": { - "title": "Contraseña", - "description": "Usa una contraseña fuerte que no reutilices en ningún otro sitio.", - "current": "Contraseña actual", - "new": "Nueva contraseña", - "newHint": "Al menos 8 caracteres.", - "confirm": "Confirmar nueva contraseña", - "update": "Actualizar contraseña", - "updating": "Actualizando…" + "nav": { + "home": "Inicio", + "dashboards": "Paneles", + "dashboardList": "Lista de paneles", + "visualizationList": "Lista de widgets", + "newDashboard": "Nuevo panel", + "newVisualization": "Nuevo widget", + "threatManagement": "Gestión de amenazas", + "alerts": "Alertas", + "incidents": "Incidentes", + "adversaryView": "Vista de adversarios", + "soar": "SOAR", + "flows": "Flujos", + "executionHistory": "Historial de ejecuciones", + "interactiveConsole": "Consola interactiva", + "logExplorer": "Explorador de logs", + "userAuditor": "Auditor de usuarios", + "threatIntelligence": "Inteligencia de amenazas", + "threat-intel": { + "indicators": "Indicadores", + "analyzt": "Analista de IA", + "triage": "Triaje", + "report": "Informe" + }, + "compliance": "Cumplimiento", + "configure": "Configurar", + "dataSources": "Fuentes de datos", + "integrations": "Integraciones", + "alertingRules": "Reglas de alertas", + "dataProcessing": "Procesamiento de datos", + "team": "Equipo", + "settings": "Configuración", + "back": "Atrás", + "parsingFilters": "Pipelines", + "regexPatterns": "Expresiones regulares", + "taggingRules": "Reglas de etiquetado", + "overview": "Resumen", + "tenants": "Tenants", + "openMenu": "Abrir menú", + "closeMenu": "Cerrar menú", + "liveOps": "Operaciones en vivo" + }, + "dashboards": { + "title": "Paneles", + "subtitle": "Explora y edita paneles interactivos.", + "list": { + "title": "Paneles", + "create": "Nuevo", + "searchPlaceholder": "Buscar paneles…", + "loading": "Cargando paneles…", + "empty": "Aún no hay paneles.", + "rename": "Renombrar", + "delete": "Eliminar" + }, + "actions": { + "edit": "Editar", + "editWithAi": "Editar con IA" + }, + "refresh": { + "title": "Actualización automática", + "options": { + "off": "Desactivado", + "10s": "10s", + "30s": "30s", + "1m": "1m", + "5m": "5m", + "15m": "15m" + } + }, + "editor": { + "editing": "Edición", + "addWidget": "Agregar widget", + "save": "Guardar", + "discard": "Descartar", + "newTitle": "Nuevo widget", + "newSubtitle": "Elige un tipo de gráfico, selecciona una fuente de datos y dale forma visualmente. El SQL se genera automáticamente.", + "editTitle": "Editar widget", + "editSubtitle": "Ajusta la definición del gráfico. Los cambios se aplican en todos los lugares donde se usa este widget.", + "loading": "Cargando widget…", + "notFoundTitle": "Widget no encontrado", + "notFoundSubtitle": "Puede que haya sido eliminada o que no tengas acceso a ella.", + "backToDashboard": "Volver al panel", + "chartType": { + "title": "Tipo de gráfico" + }, + "chartTypes": { + "bar": { + "label": "Barras", + "description": "Compara valores entre categorías." + }, + "line": { + "label": "Línea", + "description": "Tendencias sobre un eje ordenado." + }, + "area": { + "label": "Área", + "description": "Línea rellena — resalta el volumen." + }, + "pie": { + "label": "Pastel", + "description": "Proporción del total por categoría." + }, + "metric": { + "label": "Métrica", + "description": "Un único valor escalar." + }, + "table": { + "label": "Tabla", + "description": "Filas agregadas." + }, + "list": { + "label": "Lista", + "description": "Filas sin procesar y sin agregación." + }, + "region_map": { + "label": "Mapa de coordenadas", + "description": "Coloca marcadores en un mapamundi usando coordenadas de latitud y longitud." + }, + "text": { + "label": "Texto", + "description": "Texto libre o salida simple por fila." + } + }, + "dataSource": { + "title": "¿Qué datos?", + "dataset": "Conjunto de datos", + "noDatasetHint": "Elige un conjunto de datos para habilitar condiciones y agrupación." + }, + "widgetTitle": { + "label": "Título", + "placeholder": "Opcional — usa el tipo de gráfico por defecto" + }, + "dataset": { + "placeholder": "Selecciona un conjunto de datos…", + "loading": "Cargando conjuntos de datos…" + }, + "filters": { + "title": "Incluir solo eventos donde…", + "empty": "Sin condiciones: se incluyen todos los eventos del rango de tiempo.", + "add": "Agregar condición", + "remove": "Quitar", + "field": "Campo", + "fieldPlaceholder": "p. ej. host.name", + "operator": "Operador", + "value": "Valor", + "valuePlaceholder": "Valor", + "from": "Desde", + "to": "Hasta", + "noValue": "No se necesita valor", + "listPlaceholder": "Valores separados por coma" + }, + "operators": { + "IS": "es", + "IS_NOT": "no es", + "IS_ONE_OF_TERMS": "es uno de", + "IS_GREATER_THAN": "es mayor que", + "IS_LESS_THAN_OR_EQUALS": "es menor o igual que", + "IS_BETWEEN": "está entre", + "CONTAIN": "contiene", + "DOES_NOT_CONTAIN": "no contiene", + "START_WITH": "empieza con", + "ENDS_WITH": "termina con", + "EXIST": "existe", + "DOES_NOT_EXIST": "no existe" + }, + "dimension": { + "title": "Agrupar por", + "field": "Campo", + "placeholder": "Elige un campo para agrupar…" + }, + "table": { + "hint": "Muestra todos los campos de los registros. Agrega columnas para elegir algunos.", + "columnsTitle": "Columnas", + "allColumns": "Se mostrarán todas las columnas. Agrega campos para elegir columnas específicas.", + "addColumn": "Agregar una columna…", + "removeColumn": "Quitar columna" + }, + "chartPreview": { + "title": "Vista previa del gráfico", + "noQuery": "Elige un conjunto de datos para ver la vista previa.", + "error": "La consulta de vista previa falló." + }, + "chartTypeChip": { + "label": "Gráfico:" + }, + "chartTypeModal": { + "title": "Elige un tipo de gráfico", + "subtitle": "Elige cómo visualizar los datos. Puedes cambiarlo después.", + "confirm": "Continuar", + "swapTitle": "Cambiar tipo de gráfico", + "swapConfirm": "Aplicar" + }, + "saveVisualization": "Guardar widget", + "fieldSelect": { + "loading": "Cargando campos…", + "choose": "Elige un campo…" + }, + "toast": { + "notReady": "Elige un conjunto de datos, y un campo por el que desglosar, antes de guardar." + }, + "breakdown": { + "title": "Desglosar por", + "topValuesTable": "Tabla de valores principales", + "time": "En el tiempo", + "field": "Valores más frecuentes", + "interval": "Tamaño del intervalo", + "intervalAuto": "Automático", + "limit": "Cuántos", + "limitPlaceholder": "Predeterminado (50)", + "splitHint": "Opcional: una línea por cada valor de este campo." + }, + "editFilters": "Edit filters" + }, + "grid": { + "empty": "Este panel aún no tiene widgets.", + "missingVisualization": "Widget no disponible", + "unknownVisualization": "Widget" + }, + "widget": { + "renderError": "No se pudo renderizar este widget.", + "count": "Conteo", + "loading": "Cargando datos…", + "queryError": "No se pudieron cargar los datos del widget.", + "noData": "Sin datos para el rango de tiempo seleccionado.", + "regionMapEmpty": "No hay puntos con lat/lon válidos.", + "regionMapShapeHint": "El SQL debe devolver columnas de latitud y longitud (o un arreglo value [lat, lon, count]).", + "regionMapUnnamed": "(sin nombre)", + "regionMapValue": "valor: {{value}}", + "editAriaLabel": "Editar widget", + "removeAriaLabel": "Quitar widget", + "moveBack": "Mover atrás", + "moveForward": "Mover adelante", + "width": "Ancho", + "height": "Alto", + "widthSmall": "1 col", + "widthMedium": "2 cols", + "widthLarge": "3 cols", + "heightNormal": "Normal", + "heightTall": "Alto", + "incompleteSpec": "A este widget le falta parte de su pregunta." + }, + "form": { + "createTitle": "Nuevo panel", + "renameTitle": "Editar panel", + "name": "Nombre", + "namePlaceholder": "p. ej. Vista general de red", + "description": "Descripción", + "descriptionPlaceholder": "Opcional", + "cancel": "Cancelar", + "create": "Crear", + "save": "Guardar" + }, + "confirm": { + "deleteTitle": "Eliminar panel", + "delete": "¿Eliminar el panel «{{name}}»? Esta acción no se puede deshacer.", + "deleteWidgetsTitle": "Eliminar widgets", + "deleteWidgets_one": "¿Eliminar este widget? Esta acción no se puede deshacer.", + "deleteWidgets_other": "¿Eliminar {{count}} widgets? Esta acción no se puede deshacer.", + "dismissTitle": "Quitar panel", + "dismiss": "¿Quitar el panel predeterminado «{{name}}»? Después podrás crear uno nuevo a partir de él con \"Nuevo\" → \"Desde una existente\"." + }, + "page": { + "noSelection": "Elige un panel de la lista o crea uno para comenzar.", + "loading": "Cargando widgets…" + }, + "toast": { + "created": "Panel creado.", + "createFailed": "No se pudo crear el panel.", + "updated": "Panel actualizado.", + "updateFailed": "No se pudo actualizar el panel.", + "deleted": "Panel eliminado.", + "deleteFailed": "No se pudo eliminar el panel.", + "layoutSaved": "Distribución guardada.", + "layoutSaveFailed": "No se pudo guardar la distribución.", + "visualizationCreated": "Widget creado.", + "visualizationCreateFailed": "No se pudo crear el widget.", + "visualizationUpdated": "Widget actualizado.", + "visualizationUpdateFailed": "No se pudo actualizar el widget.", + "visualizationDeleted": "Widget eliminado.", + "visualizationDeleteFailed": "No se pudo eliminar el widget.", + "filterCreated": "Filtro creado.", + "filterUpdated": "Filtro actualizado.", + "filterDeleted": "Filtro eliminado.", + "filterCreateFailed": "No se pudo crear el filtro.", + "filterUpdateFailed": "No se pudo actualizar el filtro.", + "filterDeleteFailed": "No se pudo eliminar el filtro.", + "filtersSaved": "Filters saved.", + "filtersSaveFailed": "Could not save filters." + }, + "newDashboard": { + "title": "Nuevo panel", + "subtitle": "Crea un panel en blanco. Podrás agregar widgets después de guardarlo.", + "modeManual": "Crear manualmente", + "modeAi": "Con IA", + "aiLocked": "Activa SOC-AI y configúralo para poder usar esto.", + "aiDescriptionLabel": "¿Qué querés que muestre este panel?", + "aiDescriptionPlaceholder": "ej. Logins fallidos por país, últimos 7 días", + "aiCreate": "Crear con IA", + "aiOpenerWithDetails": "Creá un panel llamado \"{{name}}\" que muestre: {{description}}" + }, + "newVisualization": { + "title": "Nuevo widget", + "subtitle": "Define un gráfico reutilizable a partir de una consulta SQL y una configuración de ECharts.", + "sqlQuery": "Consulta SQL", + "sqlQueryPlaceholder": "SELECT bucket, count(*) FROM logs GROUP BY bucket", + "sqlQueryHint": "Usa los marcadores timeFilter, from y to (entre dobles llaves) para aplicar el selector de tiempo al renderizar.", + "config": "Configuración del gráfico (opción de ECharts, JSON)", + "configHint": "Debe ser JSON válido. Las filas del SQL se exponen como `dataset.source` — conecta tus series con `encode`.", + "configError": "JSON no válido: {{error}}" + }, + "visualizationList": { + "title": "Widgets", + "subtitle": "{{count}} widget(s) disponible(s).", + "subtitleFiltered": "Mostrando {{shown}} de {{total}}.", + "create": "Nueva", + "searchPlaceholder": "Buscar widgets…", + "loading": "Cargando widgets…", + "empty": "Aún no hay widgets.", + "emptyFiltered": "Ningún widget coincide con los filtros actuales.", + "delete": "Eliminar", + "deleteTitle": "Eliminar widget", + "confirmDelete": "¿Eliminar el widget «{{name}}»? Esta acción no se puede deshacer.", + "filters": { + "search": "Buscar", + "chartType": "Tipo de gráfico", + "allChartTypes": "Todos los tipos de gráfico", + "source": "Fuente", + "allSources": "Todas las fuentes", + "createdAt": "Creada", + "modifiedAt": "Modificada", + "createdRangeTitle": "Rango personalizado — Creada", + "modifiedRangeTitle": "Rango personalizado — Modificada", + "pickRange": "Elegir un rango", + "datePresets": { + "all": "Todo el tiempo", + "today": "Hoy", + "last7": "Últimos 7 días", + "last30": "Últimos 30 días", + "lastYear": "Último año", + "custom": "Rango personalizado" + }, + "clear": "Limpiar filtros" + }, + "col": { + "name": "Nombre", + "chartType": "Tipo de gráfico", + "source": "Fuente", + "description": "Descripción", + "created": "Creada", + "modified": "Modificada" + } + }, + "tabs": { + "dashboards": "Tableros", + "visualizations": "Widgets", + "newDashboard": "Nuevo tablero", + "unsetDefault": "Quitar predeterminado", + "options": "Opciones" + }, + "picker": { + "none": "Seleccionar tablero", + "search": "Buscar tableros…", + "new": "Nuevo tablero", + "setDefault": "Marcar como predeterminado", + "empty": "Sin tableros" + }, + "empty": { + "title": "Aún no hay tableros", + "body": "Crea tu primer tablero para ver tus datos de seguridad de un vistazo.", + "cta": "Crear tablero" + }, + "filters": { + "addTitle": "Añadir filtro", + "editTitle": "Editar filtro", + "removeTitle": "Eliminar filtro", + "removeConfirm": "¿Eliminar el filtro \"{{label}}\"? Esta acción no se puede deshacer.", + "remove": "Eliminar", + "editAria": "Editar filtro", + "removeAria": "Eliminar filtro", + "saving": "Guardando…", + "addChip": "Añadir filtro", + "chooseValue": "Choose…", + "selected": "selected", + "loading": "Loading values…", + "searchPlaceholder": "Search values…", + "noValues": "No values available.", + "loadError": "Could not load values.", + "clear": "Clear", + "editorTitle": "Dashboard filters", + "editorHint": "Add dropdown chips that filter every widget on this dashboard.", + "emptyEditor": "No filter chips yet. Add one to get started.", + "cancel": "Cancel", + "save": "Save", + "field": { + "dataset": "Data set", + "field": "Field", + "chooseField": "Choose a field…", + "label": "Label", + "labelPlaceholder": "e.g. Host", + "placeholder": "Placeholder", + "placeholderPlaceholder": "e.g. Pick a host", + "multiple": "Multiple", + "searchable": "Searchable" + } + }, + "duplicate": { + "copyName": "{{name}} (copia)" + } }, - "sessions": { - "title": "Sesiones activas", - "description": "Dispositivos con sesión iniciada en tu cuenta.", - "loading": "Cargando sesiones…", - "empty": "No hay sesiones activas.", - "thisDevice": "Este dispositivo", - "unknownIp": "IP desconocida", - "unknownDevice": "Dispositivo desconocido", - "deviceLabel": "{{browser}} en {{os}}", - "signedIn": "Inició sesión {{time}}", - "revoke": "Revocar", - "revoking": "Revocando…", - "signOutOthers": "Cerrar todas las demás sesiones", - "signingOut": "Cerrando…" + "settings": { + "title": "Configuración", + "license": "Licencia", + "notifications": "Notificaciones", + "connectionKey": "Clave de conexión", + "dataRetention": "Retención de datos", + "indices": "Índices", + "theme": "Tema", + "branding": "Marca", + "apiKeys": "Claves API", + "identityProviders": "Proveedores de identidad", + "email": "Configuración de correo", + "dateFormat": "Formato de fecha", + "language": "Idioma", + "auditLogs": "Registros de auditoría", + "about": "Acerca de", + "socAi": "SOC-AI", + "supportAccess": "Acceso de soporte", + "threatwinds": "Integración de ThreatWinds" + }, + "topbar": { + "theme": { + "light": "Modo claro", + "dark": "Modo oscuro" + }, + "manageLicense": "Gestionar licencia", + "profile": { + "profile": "Perfil", + "license": "Licencia", + "logout": "Cerrar sesión" + } }, - "tfa": { - "title": "Autenticación en dos pasos", - "description": "Agrega una capa extra de seguridad a tu cuenta.", - "loading": "Cargando…", - "methodTotp": "App de autenticación", - "methodEmail": "Código por correo", - "onTitle": "La autenticación en dos pasos está activada", - "method": "Método: {{method}}", - "configured": "Configurado", - "disable": "Desactivar", - "disableTitle": "Desactivar autenticación en dos pasos", - "disableDescription": "Ingresa tu contraseña actual para confirmar. Tu cuenta dependerá solo de la contraseña después.", - "currentPasswordPlaceholder": "Contraseña actual", - "disableConfirm": "Desactivar 2FA", - "disabling": "Desactivando…", - "offTitle": "La autenticación en dos pasos está desactivada", - "status": "Estado:", - "notConfigured": "Sin configurar", - "enable": "Activar", - "chooseMethod": "Elige un método", - "totpDesc": "Usa Google Authenticator, 1Password, etc. Recomendado.", - "emailDesc": "Recibe un código de 6 dígitos por correo al iniciar sesión.", - "noEmailHint": "Agrega un correo a tu perfil para usar el método por correo.", - "continue": "Continuar", - "starting": "Iniciando…", - "scanTitle": "Escanea el código QR", - "scanDescription": "Escanéalo con tu app de autenticación y luego ingresa el código de 6 dígitos que muestra.", - "manualKey": "O ingresa esta clave manualmente:", - "checkEmailTitle": "Revisa tu correo", - "checkEmailDescription": "Enviamos un código de 6 dígitos a {{email}}. Ingrésalo abajo.", - "resend": "Reenviar", - "verifyEnable": "Verificar y activar", - "verifying": "Verificando…" + "notifications": { + "title": "Notificaciones", + "markAllRead": "Marcar todas como leídas", + "empty": "No tienes notificaciones.", + "viewAll": "Ver todas", + "markRead": "Marcar como leída", + "markUnread": "Marcar como no leída", + "delete": "Eliminar", + "subtitle": "{{total}} en total · {{unread}} sin leer", + "allCaughtUp": "Todo al día.", + "loadFailed": "No se pudieron cargar las notificaciones." }, - "actions": { - "cancel": "Cancelar" + "pagination": { + "perPage": "Por página", + "pageOf": "Página {{page}} de {{total}}", + "previous": "Anterior", + "next": "Siguiente" }, - "toast": { - "profileUpdated": "Perfil actualizado", - "emailInUse": "Ese correo ya está en uso", - "profileUpdateFailed": "No se pudo actualizar el perfil", - "passwordsNoMatch": "Las contraseñas no coinciden", - "passwordTooShort": "La contraseña debe tener al menos 8 caracteres", - "passwordChanged": "Contraseña cambiada — se cerraron las demás sesiones", - "currentPasswordWrong": "La contraseña actual es incorrecta", - "passwordChangeFailed": "No se pudo cambiar la contraseña", - "avatarTypeNotAllowed": "Tipo de imagen no permitido (usa PNG, JPEG, WEBP o GIF)", - "avatarTooLarge": "La imagen es demasiado grande (máx. 2MB)", - "avatarUpdated": "Avatar actualizado", - "avatarUploadFailed": "No se pudo subir el avatar", - "avatarRemoved": "Avatar eliminado", - "avatarRemoveFailed": "No se pudo eliminar el avatar", - "sessionsLoadFailed": "No se pudieron cargar las sesiones", - "sessionRevoked": "Sesión revocada", - "sessionRevokeFailed": "No se pudo revocar la sesión", - "othersSignedOut": "Se cerraron las demás sesiones", - "othersRevokeFailed": "No se pudieron revocar las sesiones", - "tfaEmailCodeSent": "Enviamos un código de 6 dígitos a tu correo", - "tfaNewCodeSent": "Se envió un nuevo código", - "tfaWaitResend": "Espera un momento antes de pedir un nuevo código", - "tfaResendFailed": "No se pudo reenviar el código", - "tfaEnterCode": "Ingresa el código de 6 dígitos", - "tfaEnabled": "Autenticación en dos pasos activada", - "tfaEnterPassword": "Ingresa tu contraseña actual", - "tfaDisabled": "Autenticación en dos pasos desactivada", - "tfaDisableFailed": "No se pudo desactivar 2FA", - "tfaInvalidCode": "Código inválido o expirado", - "tfaAlreadyEnabled": "2FA ya está activado", - "tfaTooManyRequests": "Demasiadas solicitudes; inténtalo en un momento", - "tfaVerifyFailed": "No se pudo verificar el código", - "genericError": "Algo salió mal", - "tfaMailUnavailable": "El segundo factor por correo necesita un servidor de correo. Configúralo en Ajustes → Configuración de correo." - } - }, - "home": { - "hero": { - "title": "¿Qué te gustaría saber a partir de tus datos de seguridad?", - "placeholder": "Investiga a Scattered Spider, ¿nos aplica?, ¿nos han atacado alguna vez?, crea una regla de detección y mantenla ajustada.", - "send": "Enviar", - "suggestions": { - "threatHunt": "Caza de amenazas", - "observableTriage": "Triaje de observables", - "writeRule": "Escribir una regla", - "systemStatus": "Estado actual del sistema" - } + "license": { + "title": "Licencia", + "subtitle": "Tu edición, capacidades y archivo de licencia.", + "loading": "Cargando licencia…", + "loadError": "No se pudo cargar la información de la licencia.", + "statusLabel": "Estado", + "status": { + "community": "Community", + "active": "Activa", + "expiring": "Por expirar", + "expired": "Expirada" + }, + "edition": "Edición", + "enterprise": "Enterprise", + "community": "Community", + "editionLine": "Edición {{edition}}", + "datasourceLimit": "Límite de datasources", + "unlimited": "Ilimitado", + "mssp": "MSSP / multi-tenant", + "enabled": "Activado", + "licenseType": "Tipo de licencia", + "instanceId": "ID de instancia", + "enterpriseUnlocked": "Funciones Enterprise desbloqueadas", + "validUntil": "Válida hasta", + "noExpiry": "Sin expiración", + "timeRemaining": "Tiempo restante", + "expiredAgo": "Expiró hace {{days}}d", + "daysShort": "{{days}}d", + "msspShort": "MSSP", + "communityEdition": "Edición Community", + "communityBlurb": "Gratuita y de código abierto. Sube una licencia Enterprise abajo para desbloquear multi-tenancy, SSO, mayores límites de datasources y cumplimiento avanzado.", + "upgrade": "Actualizar a Enterprise", + "uploadTitle": "Subir una licencia", + "uploadBlurb": "Instala o reemplaza el archivo LICENSE firmado. El servidor valida la firma y la expiración antes de aplicarlo. Solo admin.", + "installLicense": "Instalar licencia", + "chooseFile": "Seleccionar archivo", + "noFileSelected": "Ningún archivo seleccionado", + "toast": { + "installed": "Licencia instalada — edición {{edition}}.", + "adminRequired": "Se requieren privilegios de administrador para subir una licencia.", + "invalid": "Archivo de licencia inválido o expirado.", + "installFailed": "No se pudo instalar la licencia." + }, + "ingestLimit": "Volumen de ingesta", + "notMetered": "Sin medición", + "gbPerMonth": "{{gb}} GB/mes" + }, + "audit": { + "title": "Registro de auditoría", + "subtitle": "Registro de cada acción relevante para la seguridad.", + "totalEntries": "{{total}} entradas en total.", + "loadError": "No se pudo cargar el registro de auditoría", + "stats": { + "totalEntries": "Entradas totales", + "acrossAllTime": "De todo el tiempo", + "successRate": "Tasa de éxito", + "failuresOnPage_one": "{{count}} fallo en esta página", + "failuresOnPage_other": "{{count}} fallos en esta página", + "topAction": "Acción principal", + "onPage": "{{count}} en esta página", + "uniqueActors": "Actores únicos", + "includingSystem": "Incluyendo el sistema" + }, + "filters": { + "title": "Filtros", + "clear": "Limpiar", + "last24h": "Últimas 24h", + "failuresOnly": "Solo fallos", + "authEvents": "Eventos de autenticación", + "actionPrefix": "Prefijo de acción", + "actionPlaceholder": "p.ej. auth., user.update", + "status": "Estado", + "any": "Cualquiera", + "resourceType": "Tipo de recurso", + "resourceTypePlaceholder": "user, alert…", + "resourceId": "ID de recurso", + "user": "Usuario", + "userPlaceholder": "login…" + }, + "statusValue": { + "success": "Éxito", + "failure": "Fallo" + }, + "table": { + "timestamp": "Fecha y hora", + "actor": "Actor", + "action": "Acción", + "resource": "Recurso", + "status": "Estado", + "ip": "IP", + "loading": "Cargando…", + "emptyTitle": "Ninguna entrada coincide con estos filtros.", + "emptyHint": "Prueba a limpiar los filtros o ampliar el rango de fechas.", + "system": "sistema", + "view": "Ver" + }, + "drawer": { + "entry": "entrada #{{id}}", + "overview": "Resumen", + "raw": "JSON crudo", + "error": "Error", + "actor": "Actor", + "resource": "Recurso", + "ip": "IP", + "userAgent": "Agente de usuario", + "session": "Sesión", + "metadata": "Metadatos", + "copy": "Copiar", + "copied": "Copiado", + "copyJson": "Copiar JSON" + } }, - "kpis": { - "alerts24h": "Alertas (24 h)", - "openIncidents": "Incidentes abiertos", - "openIncidentsSub": "abiertos actualmente", - "highSeverity24h": "Severidad alta (24 h)", - "highSeveritySub": "de {{n}} alertas", - "activePlaybooks": "Playbooks activos", - "activePlaybooksSub": "habilitados" + "team": { + "title": "Equipo", + "subtitle": "Gestiona los usuarios y sus roles.", + "tabs": { + "members": "Miembros", + "roles": "Roles y permisos" + }, + "toast": { + "rolesLoadFailed": "No se pudieron cargar los roles", + "userLoadFailed": "No se pudo cargar el usuario", + "rolesUpdated": "Roles actualizados", + "userReactivated": "Usuario reactivado", + "userDeactivated": "Usuario desactivado", + "tfaReset": "Autenticación en dos pasos restablecida", + "invitationSent": "Invitación enviada", + "loginOrEmailInUse": "Ese usuario o correo ya está en uso", + "invalidRequest": "Solicitud inválida", + "noPermission": "No tienes permiso para hacer eso", + "userNotFound": "Usuario no encontrado", + "operationFailed": "La operación falló", + "emailInUse": "Ese correo ya está en uso", + "roleCreated": "Rol creado", + "roleUpdated": "Rol actualizado", + "roleDeleted": "Rol eliminado", + "roleNameInUse": "Ya existe un rol con ese identificador", + "roleImmutable": "Los roles del sistema no se pueden modificar", + "permissionsLoadFailed": "No se pudieron cargar los permisos", + "localUserCreated": "Usuario local creado" + }, + "members": { + "searchPlaceholder": "Buscar por nombre o correo…", + "invite": "Invitar usuario", + "colUser": "Usuario", + "colRoles": "Roles", + "col2fa": "2FA", + "colStatus": "Estado", + "loading": "Cargando usuarios…", + "loadFailed": "No se pudieron cargar los usuarios.", + "retry": "Reintentar", + "noSearchMatch": "Ningún usuario coincide con tu búsqueda.", + "none": "Aún no hay usuarios.", + "noRole": "ninguno", + "on": "Sí", + "off": "No", + "countLabel_one": "{{count}} usuario · página {{page}} de {{pages}}", + "countLabel_other": "{{count}} usuarios · página {{page}} de {{pages}}", + "federated": "SSO" + }, + "status": { + "inactive": "Inactivo", + "pendingPassword": "Contraseña pendiente", + "active": "Activo", + "pending": "Invitación pendiente", + "suspended": "Suspendido" + }, + "drawer": { + "createdBy": "creado por {{actor}}", + "loading": "Cargando…", + "profileTitle": "Perfil", + "profileSubtitle": "Solo el usuario puede editar esto, desde su propio perfil.", + "name": "Nombre", + "username": "Usuario", + "email": "Correo", + "language": "Idioma", + "accountTitle": "Cuenta", + "status": "Estado", + "statusActive": "Activo", + "statusInactive": "Inactivo", + "tfa": "2FA", + "tfaEnabled": "Activada", + "tfaNotConfigured": "No configurado", + "resetTfa": "Restablecer", + "resetTfaHint": "Desactiva el 2FA de este usuario para que lo reconfigure en su próximo inicio de sesión", + "resetTfaConfirmTitle": "¿Restablecer la autenticación en dos pasos?", + "resetTfaConfirmBody": "Esto desactiva el 2FA de {{name}}. Iniciará sesión solo con su contraseña y podrá configurarlo de nuevo desde su perfil.", + "resetTfaConfirm": "Restablecer 2FA", + "pendingPasswordNote": "Aún usa la contraseña temporal (invitación no completada).", + "lastModified": "Modificado {{time}}", + "rolesTitle": "Roles", + "rolesSubtitle": "Los roles otorgan permisos de módulo. Un usuario puede tener más de uno.", + "noRoleWarning": "Sin rol asignado — el usuario no tendrá acceso a ningún módulo.", + "deactivate": "Desactivar", + "reactivate": "Reactivar", + "waitingInvite": "Esperando a que el usuario acepte la invitación.", + "cancel": "Cancelar", + "saving": "Guardando…", + "saveRoles": "Guardar roles", + "created": "creado {{time}}", + "pendingNote": "La invitación aún no se ha aceptado.", + "federatedNote": "Inicia sesión mediante un proveedor de identidad." + }, + "invite": { + "title": "Invitar usuario", + "description": "La cuenta se crea inactiva. El usuario recibe un correo para establecer su contraseña y activarla.", + "username": "Usuario", + "usernameHint": "Al menos 3 caracteres.", + "email": "Correo", + "firstName": "Nombre", + "lastName": "Apellido", + "roles": "Roles", + "cancel": "Cancelar", + "sending": "Enviando…", + "send": "Enviar invitación", + "name": "Nombre", + "emailHint": "Es la dirección con la que iniciará sesión.", + "localDescription": "La cuenta se crea con una contraseña y se activa de inmediato. No se envía ningún correo.", + "modeInvite": "Invitar usuario", + "modeLocal": "Crear usuario local", + "passwordLabel": "Contraseña", + "passwordPlaceholder": "Establezca una contraseña segura", + "localUserNote": "Este usuario no recibirá un correo y será activado automáticamente.", + "createLocal": "Crear usuario", + "passwordRules": { + "length": "Al menos 8 caracteres", + "case": "Al menos una mayúscula y una minúscula", + "special": "Al menos un carácter especial" + }, + "emailInvalid": "Introduzca una dirección de correo válida" + }, + "rolePicker": { + "none": "No hay roles disponibles." + }, + "roles": { + "loading": "Cargando roles…", + "loadFailed": "No se pudieron cargar los permisos de los roles.", + "readonlyNote": "Los roles y sus permisos los define el sistema y son de solo lectura. Asígnalos a los usuarios desde la pestaña Miembros.", + "permissionsCount_one": "{{count}} permiso", + "permissionsCount_other": "{{count}} permisos", + "modulesCount_one": "{{count}} módulo", + "modulesCount_other": "{{count}} módulos", + "matrixTitle": "Matriz de permisos", + "matrixSubtitle": "Lo que cada rol puede hacer, por módulo.", + "permission": "Permiso", + "systemNote": "Los roles del sistema vienen con la plataforma y no se pueden editar. Los que crees pertenecen a este tenant.", + "newRole": "Nuevo rol", + "edit": "Editar", + "delete": "Eliminar", + "systemBadge": "Sistema", + "createTitle": "Nuevo rol", + "editTitle": "Editar rol", + "editorSubtitle": "Elige qué puede hacer este rol. Un usuario puede tener más de uno.", + "nameLabel": "Identificador", + "nameHint": "Se usa en el código y en la API. Por ejemplo, ROLE_AUDITOR.", + "displayNameLabel": "Nombre visible", + "descriptionLabel": "Descripción", + "permissionsLabel": "Permisos", + "selectedCount": "{{count}} seleccionados", + "toggleAll": "todos", + "loadingPermissions": "Cargando permisos…", + "save": "Guardar rol", + "deleteConfirmTitle": "¿Eliminar este rol?", + "deleteConfirmBody": "Se eliminará {{name}}. Los usuarios que solo tengan este rol se quedarán sin acceso a los módulos." + }, + "langDefault": "Predeterminado del sistema", + "relative": { + "justNow": "ahora mismo", + "minutesAgo": "hace {{count}} min", + "hoursAgo": "hace {{count}} h", + "daysAgo": "hace {{count}} d" + }, + "roleNames": { + "ROLE_ADMIN": "Administrador", + "ROLE_USER": "Usuario" + }, + "roleDescriptions": { + "ROLE_ADMIN": "Acceso total a todos los recursos", + "ROLE_USER": "Usuario estándar con acceso de lectura a nivel de módulo" + }, + "actions": { + "read": "Lectura", + "write": "Escritura", + "delete": "Eliminación" + }, + "resources": { + "adaudit": "Auditoría AD", + "alerts": "Alertas", + "audit": "Registro de auditoría", + "compliance": "Cumplimiento", + "config": "Configuración", + "dashboards": "Paneles", + "datasources": "Datasources", + "eventprocessing": "Procesamiento de eventos", + "idp": "Proveedores de identidad", + "incidents": "Incidentes", + "integrations": "Integraciones", + "loganalyzer": "Analizador de logs", + "opensearch": "OpenSearch", + "roles": "Roles", + "soar": "SOAR", + "users": "Usuarios", + "notifications": "Notificaciones", + "socai": "SOC AI", + "tenant": "Tenants", + "threatintel": "Inteligencia de amenazas" + } }, - "datasources": { - "title": "Fuentes de datos", - "viewAll": "Ver todo", - "ofTotal": "de {{n}}", - "datasources": "fuentes de datos", - "sendingData": "enviando datos", - "totalEvents": "Eventos totales", - "noData": "Sin datos de ingesta en esta ventana" + "apiKeys": { + "title": "Claves API", + "subtitle": "Tokens de acceso programático para la API de UTMStack.", + "new": "Nueva clave API", + "searchPlaceholder": "Buscar por nombre o IP permitida…", + "refresh": "Actualizar", + "loading": "Cargando claves API…", + "loadFailed": "No se pudieron cargar las claves API.", + "retry": "Reintentar", + "noSearchMatch": "Ninguna clave API coincide con tu búsqueda.", + "empty": "Aún no hay claves API. Crea una para empezar.", + "anyIp": "Cualquier IP", + "never": "Nunca", + "count_one": "{{count}} clave · página {{page}} de {{pages}}", + "count_other": "{{count}} claves · página {{page}} de {{pages}}", + "enterprise": { + "title": "Las claves API son una función Enterprise", + "body": "Emite, restringe y rota claves API para acceso programático a la API de UTMStack. Esta capacidad está disponible en la edición Enterprise.", + "upgrade": "Actualizar a Enterprise", + "manageLicense": "Gestionar tu licencia" + }, + "col": { + "name": "Nombre", + "allowedIps": "IPs permitidas", + "created": "Creada", + "lastRotated": "Última rotación", + "expires": "Expira", + "status": "Estado", + "actions": "Acciones" + }, + "status": { + "active": "Activa", + "expiring": "Por expirar", + "expired": "Expirada" + }, + "action": { + "rotate": "Rotar", + "edit": "Editar", + "delete": "Eliminar" + }, + "dialog": { + "editTitle": "Editar clave API", + "newTitle": "Nueva clave API", + "name": "Nombre", + "namePlaceholder": "ci-pipeline", + "allowedIps": "IPs permitidas", + "allowedIpsHint": "Separadas por comas. Deja vacío para permitir cualquier IP.", + "expires": "Expira", + "expiresHint": "Deja vacío para una clave que nunca expira.", + "secretNote": "El token secreto se muestra una sola vez, justo tras la creación. Cópialo entonces — no se puede recuperar después (solo rotar).", + "cancel": "Cancelar", + "saving": "Guardando…", + "saveChanges": "Guardar cambios", + "createKey": "Crear clave" + }, + "confirm": { + "deleteTitle": "Eliminar clave API", + "rotateTitle": "Rotar clave API", + "deleteBody": "¿Eliminar {{name}}? Cualquier cliente que la use perderá el acceso de inmediato. Esto no se puede deshacer.", + "rotateBody": "¿Rotar {{name}}? Se emite un nuevo secreto y el actual deja de funcionar de inmediato. El nuevo token se muestra una sola vez.", + "cancel": "Cancelar", + "working": "Procesando…", + "delete": "Eliminar", + "rotate": "Rotar" + }, + "reveal": { + "title": "Clave API creada", + "note": "Copia este secreto ahora — para {{name}}. No se volverá a mostrar. Si lo pierdes, rota la clave.", + "copied": "Copiado", + "copy": "Copiar", + "done": "Listo" + }, + "toast": { + "updated": "Clave API actualizada", + "secretIssueFailed": "Clave creada, pero no se pudo emitir el secreto. Usa Rotar para obtener uno.", + "deleted": "Clave API eliminada" + }, + "error": { + "nameTaken": "Ya existe una clave API con ese nombre", + "enterpriseRequired": "Las claves API requieren la edición Enterprise", + "notFound": "Clave API no encontrada", + "invalidRequest": "Solicitud inválida", + "failed": "Operación fallida" + } }, - "span": { - "recent": "ventana reciente", - "days_one": "último {{count}} día", - "days_other": "últimos {{count}} días", - "hours": "últimas {{n}} h" + "idp": { + "title": "Proveedores de identidad", + "subtitle": "Inicio de sesión único SAML 2.0 para tu organización.", + "add": "Agregar proveedor", + "enterprise": { + "title": "El SSO es una función Enterprise", + "body": "Conecta un proveedor de identidad SAML 2.0 (Entra ID, Okta, Google Workspace…) para que tu equipo inicie sesión con tu IdP. El inicio de sesión único está disponible en la edición Enterprise.", + "upgrade": "Actualizar a Enterprise" + }, + "loading": "Cargando proveedores de identidad…", + "loadFailed": "No se pudieron cargar los proveedores de identidad.", + "retry": "Reintentar", + "empty": { + "title": "No hay proveedores de identidad configurados", + "body": "Agrega un proveedor SAML 2.0 para que tu equipo inicie sesión con tu IdP corporativo." + }, + "card": { + "enable": "Habilitar", + "disable": "Deshabilitar", + "active": "Activo", + "disabled": "Deshabilitado", + "metadataUrl": "URL de metadatos", + "spEntityId": "SP Entity ID", + "spAcsUrl": "SP ACS URL", + "loginUrl": "URL de inicio de sesión", + "copy": "Copiar", + "edit": "Editar", + "delete": "Eliminar", + "jit": "Alta", + "jitOn": "crea cuentas en el primer acceso", + "sync": "Roles", + "syncOn": "se reaplican en cada acceso" + }, + "form": { + "addTitle": "Agregar proveedor de identidad", + "editTitle": "Editar proveedor de identidad", + "name": "Nombre", + "nameHint": "Único. Se usa en la URL de SSO.", + "providerType": "Tipo de proveedor", + "providerTypeHint": "Una etiqueta, p. ej. azure, okta, google.", + "metadataUrl": "URL de metadatos del IdP", + "spEntityId": "SP Entity ID", + "spAcsUrl": "SP ACS URL", + "certificate": "Certificado SP (PEM)", + "privateKey": "Llave privada SP (PEM)", + "privateKeyHintEdit": "Déjalo vacío para conservar la llave guardada.", + "privateKeyHintCreate": "Requerida. Se guarda cifrada; no se vuelve a mostrar.", + "privateKeyUnchanged": "•••••••• (sin cambios)", + "active": "Activo (mostrar en la página de inicio de sesión)", + "cancel": "Cancelar", + "saving": "Guardando…", + "save": "Guardar cambios", + "create": "Crear proveedor", + "issuer": "URL del emisor", + "issuerHint": "El descubrimiento se hace contra esta URL; el proveedor debe servir /.well-known/openid-configuration bajo ella.", + "clientId": "ID de cliente", + "redirectUrl": "URL de retorno", + "redirectUrlHint": "Registra exactamente esta URL en el proveedor.", + "host": "Servidor", + "port": "Puerto", + "startTls": "TLS", + "startTlsOn": "Usar StartTLS", + "bindDn": "DN de conexión", + "bindDnHint": "Una cuenta de servicio que pueda buscar en el directorio.", + "baseDn": "DN base", + "userFilter": "Filtro de usuario", + "userFilterHint": "Debe contener %s, donde se sustituye la dirección escrita al entrar.", + "emailAttribute": "Atributo de correo", + "nameAttribute": "Atributo de nombre", + "groupAttribute": "Atributo de grupo", + "provisioning": "Cuentas y roles", + "provisioningHint": "Qué ocurre cuando entra alguien por quien responde el directorio.", + "jit": "Crear la cuenta en el primer acceso", + "defaultRole": "Rol por defecto", + "defaultRoleHint": "Se concede cuando ningún grupo casa. Sin él, un acceso sin coincidencia se rechaza.", + "noDefaultRole": "Ninguno", + "groupsAttribute": "Atributo de grupos", + "groupsAttributeHint": "Dónde pone el proveedor la pertenencia a grupos.", + "syncRoles": "Reaplicar roles en cada acceso", + "syncRolesHint": "Los roles que no estén en el mapeo se quitan, para que un cambio en el directorio llegue hasta aquí. Sin esto, una degradación no llega nunca.", + "mappings": "Grupo a rol", + "mappingsHint": "Un grupo del directorio a la izquierda, el rol que concede a la derecha.", + "addMapping": "Añadir", + "noMappings": "Sin mapeos. Todos reciben el rol por defecto.", + "groupPlaceholder": "Analistas SOC", + "pickRole": "Elige un rol", + "secret.saml": "Clave privada del SP", + "secret.oidc": "Secreto de cliente", + "secret.ldap": "Contraseña de conexión", + "secretHintCreate": "Se guarda cifrada y no se vuelve a mostrar.", + "secretHintEdit": "Déjalo en blanco para conservar la guardada.", + "secretUnchanged": "sin cambios", + "errors": { + "required": "Este campo es obligatorio.", + "url": "Debe ser una URL http(s) válida.", + "httpsUrl": "Debe ser una URL https válida.", + "hostname": "Introduce un host o IP sin esquema (p. ej. ldap.ejemplo.com).", + "port": "El puerto debe ser un número entero entre 0 y 65535.", + "pemCertificate": "No parece un certificado PEM (faltan -----BEGIN/END CERTIFICATE-----).", + "pemKey": "No parece una clave privada PEM (faltan -----BEGIN/END PRIVATE KEY-----).", + "userFilterPlaceholder": "El filtro debe contener %s, donde se sustituye la dirección de inicio de sesión.", + "userFilterUnbalanced": "Hay paréntesis desequilibrados: la búsqueda no devolverá nada.", + "nameFormat": "Usa letras, números, puntos, guiones o guiones bajos (máx. 64). Aparece en la URL de SSO, por lo que no admite espacios.", + "redirectUrl": "Debe ser una URL https válida, o una URL http de loopback (localhost / 127.0.0.1 / [::1]).", + "entityId": "Debe ser una URI válida, p. ej. https://utmstack.example.com/sp." + } + }, + "delete": { + "title": "Eliminar proveedor de identidad", + "body": "¿Eliminar {{name}}? Los usuarios ya no podrán iniciar sesión a través de él. Esto no se puede deshacer.", + "cancel": "Cancelar", + "deleting": "Eliminando…", + "confirm": "Eliminar" + }, + "toast": { + "enabled": "Proveedor habilitado", + "disabled": "Proveedor deshabilitado", + "created": "Proveedor de identidad creado", + "updated": "Proveedor de identidad actualizado", + "deleted": "Proveedor de identidad eliminado", + "paidPlan": "El SSO SAML requiere un plan de pago", + "enterpriseRequired": "El SSO requiere la edición Enterprise", + "notFound": "Proveedor de identidad no encontrado", + "invalid": "Configuración inválida", + "failed": "La operación falló" + }, + "providerType": { + "saml": "SAML 2.0", + "oidc": "OpenID Connect", + "ldap": "LDAP / Active Directory", + "comingSoon": "aún no disponible" + } }, - "mitre": { - "title": "Técnicas MITRE ATT&CK principales", - "explore": "Explorar", - "empty": "Aún no hay alertas con técnica asignada" + "userAuditor": { + "title": "Auditor de usuarios", + "subtitle": "Cuentas de Active Directory observadas en tus logs de seguridad de Windows — descubiertas a partir de eventos de creación, inicio de sesión y borrado.", + "export": "Exportar", + "accountsChip": "{{count}} cuentas", + "overview": { + "title": "Inventario de cuentas", + "active": "activas", + "disabled": "deshabilitadas", + "deleted": "borradas", + "seen24h": "{{count}} vistas en las últimas 24 horas", + "byDomain": "Por dominio", + "grouped": "{{count}} agrupados", + "unassigned": "{{count}} sin asignar" + }, + "views": { + "all": "Todas las cuentas", + "windows": "Windows", + "linux": "Linux", + "active": "Activas", + "disabled": "Deshabilitadas", + "deleted": "Borradas", + "service": "Cuentas de servicio", + "stale": "Inactivas (30d+)", + "o365": "O365", + "azure": "Azure", + "gcp": "GCP", + "aws": "AWS" + }, + "searchPlaceholder": "Buscar por nombre de cuenta o SID…", + "allTenants": "Todos los tenants", + "filters": { + "add": "Añadir filtro", + "clearAll": "Limpiar todo", + "filterValues": "Filtrar valores…", + "loadingValues": "Cargando valores…", + "noValues": "No se encontraron valores.", + "pickValue": "Elige un valor para añadir el filtro.", + "empty": "(vacío)", + "cancel": "Cancelar", + "addBtn": "Añadir" + }, + "filterFields": { + "status": "Estado de ciclo de vida" + }, + "ops": { + "is": "es" + }, + "refresh": "Actualizar", + "layout": { + "list": "Lista", + "cards": "Tarjetas" + }, + "list": { + "account": "Cuenta", + "identity": "Identidad", + "sid": "SID", + "status": "Estado", + "lastLogon": "Último inicio", + "lastSeen": "Última vez vista", + "tenant": "Tenant", + "accountId": "ID de cuenta", + "identityGroup": "Grupo de identidad" + }, + "status": { + "active": "Activa", + "disabled": "Deshabilitada", + "deleted": "Borrada" + }, + "badge": { + "service": "servicio", + "stale": "inactiva" + }, + "empty": "Ninguna cuenta coincide con esta vista.", + "loadError": "No se pudieron cargar las cuentas de AD.", + "retry": "Reintentar", + "card": { + "lastLogon": "Último inicio" + }, + "pageInfo": "{{from}}–{{to}} de {{count}}", + "drawer": { + "tenantInline": "tenant {{id}}", + "serviceAccount": "cuenta de servicio", + "stale": "inactiva 30d+", + "viewInLogs": "Ver eventos en el Log Explorer", + "copySid": "Copiar SID", + "copyUid": "Copiar identidad", + "copied": "Copiado", + "identity": "Identidad", + "accountName": "Nombre de cuenta", + "domain": "Dominio", + "hostname": "Hostname", + "sid": "SID", + "uidNumber": "UID", + "machineId": "ID de máquina", + "tenant": "Tenant", + "adStatus": "Estado en AD", + "enabled": "Habilitada", + "disabled": "Deshabilitada", + "lifecycle": "Ciclo de vida", + "created": "Cuenta creada", + "lastLogon": "Último inicio de sesión", + "lastSeen": "Última vez vista en logs", + "deleted": "Cuenta borrada", + "noLifecycle": "Sin eventos de ciclo de vida.", + "aliasGroup": "Grupo de identidad", + "alias": { + "add": "Añadir grupo de identidad", + "search": "Buscar grupos…", + "none": "Aún no hay grupos", + "new": "Nuevo grupo", + "unassign": "Quitar del grupo", + "unassigned": "Sin grupo", + "newPlaceholder": "Nombre del nuevo grupo (2–64 caracteres)", + "createAndAssign": "Crear y asignar", + "nameTooShort": "El nombre debe tener entre 2 y 64 caracteres", + "updated": "Grupo de identidad actualizado", + "updateFailed": "No se pudo actualizar el grupo de identidad" + } + }, + "relative": { + "justNow": "ahora mismo", + "minutesAgo": "hace {{count}}m", + "hoursAgo": "hace {{count}}h", + "daysAgo": "hace {{count}}d" + }, + "none": "—", + "allIdentities": "Todos los grupos de identidad", + "noneIdentity": "Sin grupo de identidad" + }, + "connectionKey": { + "title": "Clave de conexión", + "subtitle1": "La clave que los agentes presentan al registrarse en esta instancia.", + "subtitleEmphasis": "Solo se usa para la instalación de agentes", + "subtitle2": "— no para colectores, integraciones ni la API. La gestiona el agent-manager.", + "status": { + "label": "Estado", + "loading": "Cargando…", + "unavailable": "Agent-manager no disponible", + "active": "Activa", + "unavailableHint": "No se pudo contactar al agent-manager para leer la clave.", + "activeHint": "Los agentes pueden registrarse con esta clave." + }, + "token": { + "title": "Clave de conexión", + "subtitle": "Trata este valor como una credencial. Rotarla genera una nueva clave para futuras instalaciones de agentes — los agentes ya registrados siguen funcionando.", + "loadFailedTitle": "No se pudo cargar la clave de conexión", + "unavailableTitle": "Clave de conexión no disponible", + "loadFailedHint": "La clave la gestiona el agent-manager, que no respondió. Inténtalo de nuevo en un momento.", + "retry": "Reintentar", + "show": "Mostrar clave", + "hide": "Ocultar clave", + "copy": "Copiar", + "copied": "Copiado", + "regenerate": "Regenerar clave de conexión", + "confirmTitle": "¿Regenerar la clave?", + "confirmBody": "Las nuevas instalaciones de agentes necesitarán la nueva clave. Los agentes ya registrados seguirán funcionando. No se puede deshacer.", + "regenerating": "Regenerando…", + "confirmYes": "Sí, regenerar", + "cancel": "Cancelar" + }, + "security": { + "title": "Recomendaciones de seguridad", + "subtitle": "Buenas prácticas para proteger esta credencial.", + "rotateTitle": "Rota cada 90 días", + "rotateBody": "Programa una rotación periódica. UTMStack puede enviarte un recordatorio por correo cuando la clave tenga más de 90 días.", + "rotateAction": "Configurar recordatorio", + "secretTitle": "Guárdala como secreto", + "secretBody": "No la subas al control de versiones. Usa tu gestor de secretos (Vault, AWS SM, etc.) e inyéctala en el momento de la instalación.", + "auditTitle": "Audita quién la obtuvo", + "auditBody": "Cada obtención y rotación queda registrada en el journal de auditoría de la aplicación.", + "auditAction": "Ver journal de auditoría" + }, + "toast": { + "loadFailed": "No se pudo cargar la clave de conexión", + "rotated": "Clave de conexión rotada", + "rotateFailed": "No se pudo rotar la clave de conexión", + "copyFailed": "No se pudo copiar" + } }, - "assets": { - "title": "Activos más atacados", - "viewAll": "Ver todo", - "asset": "Activo", - "alerts": "Alertas", - "empty": "No hay activos atacados en las alertas recientes" + "dataRetention": { + "title": "Retención de datos", + "subtitle": "Cuánto se guarda cada conjunto de datos y cuándo sus registros dejan de ocupar disco local.", + "loading": "Cargando…", + "loadFailed": "No se pudo leer el almacén.", + "retry": "Reintentar", + "datasets": { + "logs": "Logs", + "alerts": "Alertas", + "statistics": "Estadísticas de ingesta" + }, + "holding": "{{documents}} registros · {{size}}", + "since": "desde {{date}}", + "diskUsed": "Disco al {{pct}}%", + "keep": "Eliminar después de", + "keepHint": "Un registro se elimina esos días después de ocurrir, esté donde esté guardado.", + "cold": "Mover a almacenamiento frío tras", + "coldHint": "Los registros antiguos pasan al object storage y siguen siendo consultables. 0 los deja siempre en disco local.", + "coldUnavailable": "Configura el almacenamiento frío abajo para sacar los registros antiguos del disco local.", + "coldBeforeDelete": "Los registros deben moverse antes de eliminarse: usa menos días que la vida total, o 0.", + "tieredNote": "Este conjunto mueve registros a almacenamiento frío. Volver a solo disco local exige reconstruir la tabla, así que no se puede apagar aquí.", + "days": "días", + "save": "Guardar", + "saving": "Guardando…", + "toast": { + "saved": "Retención guardada", + "noPermission": "No tienes permiso para cambiar la retención", + "saveFailed": "No se pudo guardar la retención" + }, + "coldStorage": { + "title": "Almacenamiento frío", + "hint": "Un object storage que el almacén trata como un segundo disco más lento. Los registros antiguos se mueven allí y se consultan desde el mismo sitio: no es un archivo y no hay que restaurar nada.", + "active": "En uso", + "inactive": "Sin configurar", + "writtenNotReady": "El bucket está configurado pero el almacén no lo ha tomado. Comprueba que el despliegue comparte el directorio de configuración del almacén.", + "endpoint": "URL del bucket", + "accessKey": "Access key", + "secretKey": "Secret key", + "bucketLocked": "Las credenciales se pueden cambiar cuando quieras. El bucket no, una vez hay registros dentro: las partes ya movidas lo llevan.", + "enable": "Activar almacenamiento frío", + "update": "Actualizar credenciales", + "toast": { + "saved": "Almacenamiento frío configurado", + "failed": "No se pudo configurar el almacenamiento frío" + }, + "kind": "Tipo", + "kind_s3": "Almacén de objetos compatible con S3", + "kind_local": "Carpeta local o NFS", + "kind_azure": "Azure Blob Storage", + "accountUrl": "URL de la cuenta de almacenamiento", + "container": "Contenedor", + "accountName": "Nombre de la cuenta", + "accountKey": "Clave de la cuenta", + "useRole": "Usar el rol IAM del servidor en lugar de claves", + "s3Hint": "Funciona con AWS S3 y cualquier almacén compatible con S3: MinIO, Ceph, Wasabi, Cloudflare R2 o Google Cloud Storage (endpoint https://storage.googleapis.com// con claves HMAC).", + "localHint": "Los registros pasan a la carpeta montada en /mnt/utmstack-cold dentro del almacén de eventos: un directorio normal en la carpeta de datos, o un recurso NFS montado en el host sobre /clickhouse/cold antes de iniciar el stack. No requiere credenciales.", + "changeWarning": "No migramos los datos que ya están en el destino actual. Se quedan allí y dejan de poder consultarse desde aquí hasta que copies a mano el destino anterior al nuevo." + }, + "forbidden": { + "title": "Esta página es de la plataforma", + "body": "La retención se aplica a las tablas que comparten todos los tenants, así que solo un administrador de plataforma puede verla o cambiarla. Pídeselo a uno, o entra con una cuenta de plataforma." + } }, - "compliance": { - "title": "Puntuación de cumplimiento", - "reports": "Informes", - "empty": "Aún no se han generado informes de cumplimiento" + "languageSettings": { + "title": "Idioma de la plataforma", + "subtitle": "Idioma por defecto para las pantallas pre-login, los correos del sistema y los usuarios nuevos. Cada usuario puede elegir el suyo en su perfil.", + "label": "Idioma por defecto", + "hint": "Se usa cuando un usuario no ha elegido su propio idioma.", + "save": "Guardar", + "saving": "Guardando…", + "saved": "Idioma de la plataforma actualizado", + "loadError": "No se pudo cargar la configuración de idioma", + "saveError": "No se pudo guardar la configuración de idioma" + }, + "branding": { + "title": "Marca", + "subtitle": "Personaliza UTMStack con la identidad de tu organización — se aplica en todo: la pantalla de login, el menú lateral, los correos y los informes.", + "enterpriseRequired": "El white-label es una función Enterprise.", + "manageLicense": "Gestionar licencia", + "enable": { + "title": "White-label", + "description": "Reemplaza la marca UTMStack por la tuya en toda la plataforma.", + "label": "Activar white-label" + }, + "identity": { + "title": "Identidad", + "productName": "Nombre del producto", + "productNameHint": "Se muestra en la barra de título, el menú lateral y los correos.", + "accent": "Color de acento", + "accentHint": "Color primario de botones, enlaces y estados activos.", + "custom": "Color personalizado" + }, + "logos": { + "title": "Logos", + "hint": "PNG, SVG, WEBP, JPG o ICO. Hasta 5 MB.", + "logo": "Logo (claro)", + "logoDark": "Logo (oscuro)", + "favicon": "Favicon" + }, + "reports": { + "title": "Recursos de informes", + "hint": "Incrustados en los informes PDF generados.", + "reportLogo": "Logo de informe", + "reportCover": "Portada de informe" + }, + "asset": { + "upload": "Subir", + "replace": "Reemplazar" + }, + "save": "Guardar cambios", + "saving": "Guardando…", + "saved": "Marca actualizada", + "saveError": "No se pudo guardar la marca", + "uploaded": "Imagen subida", + "uploadError": "No se pudo subir la imagen", + "loadError": "No se pudo cargar la marca", + "enterprise": { + "title": "La marca blanca es una función Enterprise", + "body": "Sustituye el nombre del producto, el logotipo y la portada de los informes por los tuyos, para que el panel y todo lo que genera lleven tu marca y no la de UTMStack.", + "upgrade": "Actualizar a Enterprise" + }, + "restore": "Restaurar los valores de UTMStack", + "restored": "Marca restaurada a los valores de UTMStack" + }, + "emailConfig": { + "title": "Configuración de correo", + "subtitle": "Servidor SMTP usado para enviar notificaciones de alertas, informes y correos de cuenta.", + "server": { + "title": "Servidor SMTP", + "host": "Host", + "hostHint": "Nombre del servidor SMTP.", + "port": "Puerto", + "encryption": "Cifrado", + "username": "Usuario", + "password": "Contraseña", + "passwordSetHint": "Hay una contraseña guardada. Déjalo vacío para conservarla, o escribe una nueva para cambiarla." + }, + "encryptionOpt": { + "TLS": "TLS", + "SSL": "SSL", + "NONE": "Ninguno" + }, + "sender": { + "title": "Remitente", + "from": "Dirección de origen", + "fromHint": "Dirección desde la que se envían los correos.", + "organization": "Nombre de la organización", + "organizationHint": "Se muestra en los correos de notificación de alertas e incidentes.", + "baseUrl": "URL base", + "baseUrlHint": "URL pública de esta instancia, usada en los enlaces de los correos." + }, + "test": { + "button": "Enviar prueba", + "sending": "Enviando…", + "sentTo": "Se enviará un correo de prueba a {{email}}.", + "success": "Correo de prueba enviado a {{email}}", + "fail": "No se pudo enviar el correo de prueba", + "fromRequired": "Define una dirección de origen antes de probar" + }, + "save": "Guardar cambios", + "saving": "Guardando…", + "saved": "Configuración de correo guardada", + "saveError": "No se pudo guardar la configuración", + "loadError": "No se pudo cargar la configuración", + "recipients": { + "alertsTitle": "Destinatarios de alertas", + "incidentsTitle": "Destinatarios de incidentes", + "to": "Para", + "cc": "CC", + "alertsHelper": "Direcciones avisadas cuando se generan nuevas alertas. Si lo dejas vacío, las alertas no se envían por correo.", + "incidentsHelper": "Direcciones avisadas cuando se crea un incidente. Si lo dejas vacío, los incidentes no se envían por correo.", + "add": "Añadir" + } }, - "health": { - "title": "Estado del sistema", - "details": "Detalles", - "services": { - "backend": "API del backend", - "opensearch": "Clúster de OpenSearch", - "socai": "Motor SOC-AI" - }, - "detail": { - "noClusterInfo": "sin información del clúster", - "disabled": "deshabilitado", - "tools": "{{n}} herramientas", - "unreachable": "inaccesible", - "pending": "…" - } - } - }, - "nav": { - "home": "Inicio", - "dashboards": "Paneles", - "dashboardList": "Lista de paneles", - "visualizationList": "Lista de widgets", - "newDashboard": "Nuevo panel", - "newVisualization": "Nuevo widget", - "threatManagement": "Gestión de amenazas", - "alerts": "Alertas", - "incidents": "Incidentes", - "adversaryView": "Vista de adversarios", - "soar": "SOAR", - "flows": "Flujos", - "executionHistory": "Historial de ejecuciones", - "interactiveConsole": "Consola interactiva", - "logExplorer": "Explorador de logs", - "userAuditor": "Auditor de usuarios", - "threatIntelligence": "Inteligencia de amenazas", - "threat-intel": { - "indicators": "Indicadores", - "analyzt": "Analista de IA", - "triage": "Triaje", - "report": "Informe" + "dateFormat": { + "title": "Fecha y hora", + "subtitle": "Cómo se muestran los timestamps en toda la plataforma. Los logs siempre se almacenan en UTC.", + "timezone": { + "title": "Zona horaria", + "hint": "Los timestamps se muestran en esta zona horaria. Los datos se almacenan en UTC.", + "system": "Predeterminado del navegador", + "now": "Ahora: {{value}}" + }, + "format": { + "title": "Formato de fecha", + "hint": "Estilo usado para fechas y horas." + }, + "styles": { + "short": "Corto", + "medium": "Medio", + "long": "Largo", + "full": "Completo" + }, + "save": "Guardar cambios", + "saving": "Guardando…", + "saved": "Configuración de fecha guardada", + "saveError": "No se pudo guardar la configuración", + "loadError": "No se pudo cargar la configuración" + }, + "about": { + "title": "Acerca de esta instancia", + "subtitle": "Versión, licencia y estado del sistema de este despliegue de UTMStack.", + "loading": "Cargando información de la instancia…", + "edition": { + "enterprise": "Enterprise", + "community": "Community" + }, + "fields": { + "hostname": "Servidor", + "instanceId": "ID de instancia", + "noInstanceMeta": "No hay metadatos de la instancia disponibles." + }, + "license": { + "title": "Licencia", + "enterpriseMssp": "Enterprise · MSSP", + "datasources": "Datasources", + "communityLimited": "Límite Community", + "unlimited": "Ilimitado", + "expires": "Expira", + "managedNote": "La edición, los límites de datasources y la carga de licencia se gestionan en la página de Licencia.", + "view": "Ver licencia", + "ingest": "Volumen de ingesta", + "notMetered": "Sin medición", + "gbPerMonth": "{{gb}} GB/mes" + }, + "services": { + "backend": { + "name": "Backend API", + "desc": "Gateway REST, autenticación y orquestación de módulos." + }, + "opensearch": { + "name": "OpenSearch", + "desc": "Almacenamiento de logs y eventos.", + "detail": "{{nodes}} nodos · {{shards}} shards" + }, + "unreachable": "Inaccesible" + }, + "status": { + "up": "Saludable", + "degraded": "Degradado", + "down": "Caído", + "unknown": "Desconocido" + }, + "health": { + "title": "Estado del sistema", + "allHealthy": "Todos los servicios saludables. Actualiza para revisar.", + "issues_one": "{{count}} servicio necesita atención.", + "issues_other": "{{count}} servicios necesitan atención.", + "refresh": "Actualizar" + }, + "usage": { + "title": "Fuentes de datos", + "subtitle": "Fuentes de datos configuradas en esta instalación.", + "ofUnlimited": "de ilimitado", + "ofLimit": "de {{limit}}", + "overLimit": "Por encima del límite licenciado — los datos que excedan el tope están en riesgo.", + "configured": "configuradas" + }, + "support": { + "title": "Soporte", + "docs": "Documentación", + "repo": "Repositorio en GitHub", + "issues": "Reportar un problema", + "website": "utmstack.com" + }, + "legal": { + "title": "Legal", + "license": "Licencia", + "security": "Divulgación de seguridad", + "copyright": "© {{year}} UTMStack. Todos los derechos reservados." + } }, - "compliance": "Cumplimiento", - "configure": "Configurar", - "dataSources": "Fuentes de datos", - "integrations": "Integraciones", - "alertingRules": "Reglas de alertas", - "dataProcessing": "Procesamiento de datos", - "team": "Equipo", - "settings": "Configuración", - "back": "Atrás", - "parsingFilters": "Pipelines", - "regexPatterns": "Expresiones regulares", - "taggingRules": "Reglas de etiquetado", - "overview": "Resumen", - "tenants": "Tenants", - "openMenu": "Abrir menú", - "closeMenu": "Cerrar menú", - "liveOps": "Operaciones en vivo" - }, - "dashboards": { - "title": "Paneles", - "subtitle": "Explora y edita paneles interactivos.", - "list": { - "title": "Paneles", - "create": "Nuevo", - "searchPlaceholder": "Buscar paneles…", - "loading": "Cargando paneles…", - "empty": "Aún no hay paneles.", - "rename": "Renombrar", - "delete": "Eliminar" + "logExplorer": { + "title": "Explorador de logs", + "eventsIn": "eventos en", + "searching": "Buscando…", + "query": { + "allDataTypes": "Todos los tipos de dato", + "dataTypes": "Tipos de dato", + "exportCsv": "Exportar CSV", + "filterDataTypes": "Filtrar tipos de dato…", + "noDataTypes": "Sin tipos de dato", + "noDataTypesMatch": "Ningún tipo de dato coincide", + "noTextSearch": "Este origen no tiene campo de texto completo — filtra por campo", + "refresh": "Actualizar", + "run": "Ejecutar", + "search": "Buscar", + "searchPlaceholder": "Buscar en todos los campos…" + }, + "time": { + "15m": "Últimos 15 minutos", + "1h": "Última hora", + "6h": "Últimas 6 horas", + "24h": "Últimas 24 horas", + "7d": "Últimos 7 días", + "30d": "Últimos 30 días" + }, + "ops": { + "is": "es", + "isNot": "no es", + "contains": "contiene", + "exists": "existe", + "between": "entre", + "search": "busca", + "isOneOf": "es uno de", + "isNotOneOf": "no es ninguno de", + "doesNotContain": "no contiene", + "startsWith": "empieza con", + "doesNotStartWith": "no empieza con", + "endsWith": "termina con", + "doesNotEndWith": "no termina con", + "doesNotExist": "no existe", + "notBetween": "no está entre", + "greaterThan": "es mayor que", + "greaterThanOrEquals": "es mayor o igual que", + "lessThan": "es menor que", + "lessThanOrEquals": "es menor o igual que" + }, + "filters": { + "label": "Filtros", + "clearAll": "Limpiar todo" + }, + "fields": { + "title": "Campos", + "filterPlaceholder": "Filtrar campos…", + "none": "Sin campos", + "selected": "Campos seleccionados", + "available": "Campos disponibles", + "topValues_one": "Top {{count}} valor", + "topValues_other": "Top {{count}} valores", + "loading": "Cargando…", + "noValues": "Sin valores", + "addColumn": "Agregar como columna", + "removeColumn": "Quitar columna de la tabla", + "filterFor": "Filtrar por el valor", + "filterOut": "Excluir el valor", + "empty": "(vacío)" + }, + "results": { + "dataTypesFailed": "No se pudieron cargar los tipos de dato.", + "endOfResults": "Cargados los {{count}} eventos", + "loadingMore": "Cargando más…", + "message": "Mensaje", + "none": "Ningún log coincide con esta consulta.", + "removeColumn": "Quitar {{field}}", + "retry": "Reintentar", + "searchFailed": "La búsqueda falló.", + "searching": "Buscando…", + "source": "Origen", + "time": "Hora", + "scope": "Buscado en {{dataset}} · {{dataType}}.", + "searchAllDataTypes": "Buscar en todos los tipos" + }, + "detail": { + "fieldsCount_one": "{{count}} campo", + "fieldsCount_other": "{{count}} campos", + "copyJson": "Copiar JSON", + "copied": "Documento copiado", + "parsedFields": "Campos parseados", + "json": "JSON", + "filterFor": "Filtrar por", + "filterOut": "Excluir", + "surrounding": "Eventos alrededor", + "surroundingHint": "Mostrar eventos ±15 min alrededor de este, de la misma fuente" + }, + "view": { + "table": "Tabla", + "chart": "Gráfico" + }, + "chart": { + "aggregateOn": "Agregar por", + "per": "cada", + "topValues": "— top 20 valores", + "building": "Construyendo gráfico…", + "failed": "No se pudo construir el gráfico para este campo.", + "noData": "Sin datos para graficar." + }, + "intervals": { + "minute": "Minuto", + "hour": "Hora", + "day": "Día", + "week": "Semana", + "month": "Mes", + "quarter": "Trimestre", + "year": "Año" + }, + "toast": { + "exportFailed": "La exportación falló" + }, + "builder": { + "add": "Agregar filtro", + "filterValues": "Filtrar valores…", + "loadingValues": "Cargando valores…", + "noValues": "Sin valores.", + "cancel": "Cancelar", + "confirm": "Agregar", + "pickValue": "Pick a value to add the filter." + }, + "related": { + "nLogs_one": "{{count}} log", + "nLogs_other": "{{count}} logs", + "truncated": "Mostrando los primeros {{count}} logs relacionados (el conjunto completo es mayor)." + }, + "saved": { + "title": "Guardadas", + "empty": "Aún no hay búsquedas guardadas", + "saveCurrent": "Guardar búsqueda actual", + "save": "Guardar", + "namePlaceholder": "Nombre de la búsqueda", + "delete": "Eliminar", + "saved": "Guardada «{{name}}»", + "loading": "Cargando…", + "loadFailed": "No se pudieron cargar las búsquedas guardadas", + "saveFailed": "No se pudo guardar la búsqueda", + "deleteFailed": "No se pudo eliminar la búsqueda", + "unreadable": "No se pudo leer esa búsqueda guardada" + } }, - "actions": { - "edit": "Editar", - "editWithAi": "Editar con IA" + "integrations": { + "title": "Integraciones", + "searchPlaceholder": "Buscar integraciones…", + "noMatch": "Ninguna integración coincide.", + "browseMarketplace": "Explorar marketplace", + "loading": "Cargando integraciones…", + "addCustom": { + "title": "Agregar integración personalizada", + "description": "Crear una nueva fuente personalizada", + "cta": "Crear" + }, + "tabs": { + "all": "Todas", + "agents": "Agentes", + "collectors": "Colectores", + "cloud": "Cloud", + "custom": "Personalizada" + }, + "kind": { + "agents & syslog": "Agente", + "device": "Colector", + "antivirus": "Colector", + "other": "Colector", + "custom": "Personalizada", + "cloud": "Cloud", + "utmstack modules": "Colector" + }, + "status": { + "configured": "Configurada", + "available": "Disponible" + }, + "card": { + "manage": "Gestionar →", + "setup": "Configurar →", + "eventsPerSec": "{{rate}} e/s", + "enabled": "Activado", + "setupShort": "Configurar" + }, + "drawer": { + "manage": "Gestionar", + "openDashboard": "Abrir panel", + "viewEvents": "Ver eventos", + "documentation": "Documentación", + "getInstallCmd": "Obtener comando de instalación", + "setupCollector": "Configurar colector", + "connect": "Conectar", + "configureCustom": "Configurar fuente personalizada", + "eventsRate": "{{rate}} eventos/s · {{count}} en 24h", + "manageRules": "Reglas", + "manageFilters": "Filtros" + }, + "setup": { + "agent": { + "howItWorksTitle": "Cómo funciona", + "howItWorksBody": "El agente {{name}} es un pequeño demonio que se ejecuta en el host y reenvía eventos locales a UTMStack sobre una conexión TLS autenticada. Se actualiza automáticamente e informa su estado de salud.", + "installTitle": "Instalar en {{name}}", + "installHint": "Ejecuta este comando en cada host {{name}} que desees monitorear. El token ya codifica tu workspace actual.", + "afterTitle": "Qué verás después de instalar", + "after1": "El host aparece bajo Fuentes de datos dentro de ~60 segundos después de que inicie el agente.", + "after2": "La telemetría comienza a fluir hacia el Log Explorer, limitada a tu workspace.", + "after3": "El agente auto-reporta CPU / memoria / estado del disco a UTMStack.", + "actionLabel": "Acción", + "platformLabel": "Plataforma", + "optionsLabel": "Opciones", + "skipCertValidation": "No validar el certificado TLS (servidor autofirmado)", + "noRemoteControl": "Deshabilitar la ejecución remota de comandos en este host", + "loadingToken": "Cargando token…", + "actions": { + "install": "Instalar", + "uninstall": "Desinstalar" + }, + "prereqTitle": "Requisitos previos a la instalación", + "prereqBody": "El agente de UTMStack se comunica con el servidor a través de los siguientes puertos. Asegúrese de que estén abiertos entre el host y UTMStack antes de instalar:", + "sensitiveWarning": "El comando siguiente contiene un token de inscripción sensible — no lo comparta.", + "uninstall": { + "title": "Desinstalar el agente", + "body": "Ejecute esto en el host para detener y eliminar el agente de UTMStack y sus servicios. Utiliza la plataforma seleccionada anteriormente." + }, + "macCompat": "Requiere macOS 11 (Big Sur) o posterior en Apple Silicon (M1/M2/M3 o más reciente). Los Mac basados en Intel no son compatibles." + }, + "collector": { + "howItWorksTitle": "Cómo funciona", + "howItWorksBody": "{{name}} no ejecuta un agente de UTMStack. En su lugar, instalas el colector de UTMStack en algún lugar de la red que tanto tu dispositivo {{name}} como UTMStack puedan alcanzar. {{name}} envía syslog al colector, el colector analiza, normaliza y reenvía eventos a UTMStack.", + "step1Title": "1 · Instalar el colector de UTMStack", + "step1Hint": "Ejecutar en un host Linux con acceso de red desde el dispositivo {{name}}.", + "step2Title": "2 · Configurar {{name}} para enviar syslog", + "step2Hint": "En el dispositivo {{name}}, apunta el reenvío de syslog a la dirección del colector en {{port}}.", + "vendorDocs": "Ver instrucciones específicas del proveedor", + "step3Title": "3 · Verificar", + "step3Body": "Dentro de algunos minutos deberías ver eventos de {{name}} bajo source: {{source}} en Log Explorer, y una nueva entrada en Fuentes de datos.", + "forwarder": { + "intro": { + "title": "Cómo funciona", + "body": "Los registros fluyen desde {{source}} hacia el UTMStack Collector, que los transmite de forma segura a UTMStack para correlación y alertas. No se instala nada en {{source}} — solo el Collector necesita ejecutarse en un host de tu red." + }, + "diagram": { + "sourceSub": "tus registros", + "forwarder": "Collector", + "forwarderSub": "escucha en {{port}}", + "utmstack": "UTMStack", + "utmstackSub": "alertas y correlación", + "flow1": "registros", + "flow2": "seguro" + }, + "noInstall": "No se instala nada en {{source}} — solo redirige sus registros al Collector.", + "install": { + "title": "Instalar el UTMStack Collector", + "body": "El Collector es un servicio Linux que recibe registros de tus dispositivos y los envía a UTMStack. Un solo Collector gestiona múltiples integraciones al mismo tiempo.", + "reuse": "¿Ya tienes un Collector en ejecución? Omite este paso — apunta {{source}} al existente usando el host y puerto indicados abajo." + }, + "tls": { + "title": "Opcional — Habilitar cifrado TLS", + "intro": "Por defecto el listener acepta TCP/UDP sin cifrar. Para cifrar el tráfico syslog en tránsito, carga primero tus certificados y luego rehabilita el listener con el protocolo tls.", + "step1": "1 · Cargar tu certificado y clave (una vez por Collector)", + "step1Note": "Puedes agregar un certificado CA como tercer argumento. Si se omite, se usa el certificado hoja como CA.", + "step2": "2 · Rehabilitar el listener con TLS" + }, + "httpsCerts": { + "title": "Carga el certificado TLS en el Collector", + "body": "Esta integración usa un listener HTTPS en el puerto {{port}}, por lo que el Collector necesita un certificado y una clave cargados antes de habilitarla:" + }, + "uninstall": { + "title": "Opcional — Desinstalar el Collector", + "body": "Ejecuta este comando en el host donde está instalado el Collector para detener el servicio y eliminar todos sus archivos." + }, + "instanceHeader": { + "title": "Cabecera de autorización", + "body": "Incluye esta cabecera Authorization en cada solicitud que envíes a la instancia. El secreto de la clave API solo se muestra una vez al generarla — cópialo entonces y pégalo en lugar del marcador de posición de abajo.", + "tabSimple": "Simple", + "tabBatch": "Lote" + }, + "manualCommand": { + "title": "Optional — Enable via the command line instead", + "intro": "Prefer the terminal? SSH into the Collector host and run the command below — it matches whatever protocol and port you have selected above.", + "certStep": "1 · Load your certificate and key (once per Collector)", + "enableStep": "2 · Enable the integration" + } + }, + "cisco": { + "source": "Cisco ASA", + "step1": { + "title": "Habilitar el listener Cisco ASA en el Collector", + "body": "En el host donde está instalado el Collector, ejecuta este comando para abrir el listener de registros Cisco ASA:", + "note": "Para usar TCP en lugar de UDP, reemplaza udp por tcp en el comando anterior." + }, + "step2": { + "title": "Configurar Cisco ASA para reenviar registros", + "body": "En tu Cisco ASA, habilita syslog y apúntalo al host del Collector en el puerto {{port}}. Ejecuta estos comandos en modo EXEC privilegiado (reemplaza con el nombre de tu interfaz interna o de gestión):" + } + }, + "ciscoSwitch": { + "source": "Cisco Switch", + "step1": { + "title": "Habilitar el listener Cisco Switch en el Collector", + "body": "En el host donde está instalado el Collector, ejecuta este comando para abrir el listener de registros Cisco Switch:", + "note": "Para usar TCP en lugar de UDP, reemplaza udp por tcp en el comando anterior." + }, + "step2": { + "title": "Configurar el switch para reenviar registros", + "body": "En modo EXEC privilegiado de tu Cisco switch, habilita syslog y apúntalo al host del Collector en el puerto {{port}}:" + } + }, + "ciscoMeraki": { + "source": "Cisco Meraki", + "step1": { + "title": "Habilitar el listener Cisco Meraki en el Collector", + "body": "En el host donde está instalado el Collector, ejecuta este comando para abrir el listener de registros Cisco Meraki:", + "note": "Para usar TCP en lugar de UDP, reemplaza udp por tcp en el comando anterior." + }, + "step2": { + "title": "Configurar Meraki para reenviar registros", + "body": "En el Dashboard de Meraki, ve a Network-wide → Configure → General, desplázate a la sección Reporting y agrega un servidor syslog con la IP del Collector y el puerto {{port}}. Selecciona todos los roles que deseas reenviar." + } + }, + "ciscoFirepower": { + "source": "Cisco Firepower", + "step1": { + "title": "Habilitar el listener Cisco Firepower en el Collector", + "body": "En el host donde está instalado el Collector, ejecuta este comando para abrir el listener de registros Cisco Firepower:", + "note": "Para usar TCP en lugar de UDP, reemplaza udp por tcp en el comando anterior." + }, + "step2": { + "title": "Configurar Firepower para reenviar registros", + "body": "En Firepower Management Center (FMC), ve a Devices → Platform Settings, edita o crea una política y navega a Syslog → Syslog Servers. Agrega la IP del Collector con el puerto {{port}} (UDP), asigna la política a tus dispositivos y despliega." + } + }, + "office365": { + "intro": { + "title": "Cómo funciona", + "body": "UTMStack se conecta a Microsoft 365 usando una app registrada en Azure AD y consulta la API de Actividad de Gestión de Office 365 para obtener eventos de auditoría y seguridad. No se instala ningún agente en tu tenant.", + "diagram": { + "source": "eventos de auditoría y seguridad", + "edge": "Management API", + "utmstackSub": "correlación y alertas" + }, + "note": "UTMStack solo requiere permisos de lectura — no se solicitan permisos de escritura." + }, + "appSection": "Registro de aplicación en Azure", + "steps": { + "azurePortal": { + "title": "Abrir Microsoft Entra ID", + "body": "Abre el Portal de Azure (portal.azure.com) y haz clic en Microsoft Entra ID." + }, + "appRegistrations": { + "title": "Ir a Registros de aplicaciones", + "body": "En el menú izquierdo, haz clic en Registros de aplicaciones." + }, + "registerApp": { + "title": "Registrar una nueva aplicación", + "body": "Haz clic en Nuevo registro. Nómbrala UTMStack O365 Agent, selecciona Solo cuentas en este directorio organizacional (Inquilino único) y haz clic en Registrar." + }, + "clientSecret": { + "title": "Crear un secreto de cliente", + "body": "Ve a Certificados y secretos → Nuevo secreto de cliente. Añade una descripción, establece el vencimiento en 730 días (24 meses) y haz clic en Agregar.", + "copyNote": "Copia el Valor del secreto inmediatamente — solo se muestra una vez y no se puede recuperar después." + }, + "apiPermissions": { + "title": "Agregar permisos de Office 365 Management API", + "body": "Ve a Permisos de API → Agregar un permiso y busca Office 365 Management APIs." + }, + "activityFeed": { + "title": "Conceder permisos de ActivityFeed", + "body": "Selecciona Permisos de aplicación y añade ActivityFeed.Read y ActivityFeed.ReadDlp. Haz clic en Conceder consentimiento de administrador y confirma." + }, + "graphPermissions": { + "title": "Agregar permisos de Microsoft Graph", + "body": "De vuelta en Agregar un permiso, haz clic en Microsoft Graph." + }, + "delegatedPermissions": { + "title": "Agregar permisos delegados de SecurityAlert", + "body": "Selecciona Permisos delegados y añade SecurityAlert.Read.All y SecurityAlert.ReadWrite.All. Haz clic en Conceder consentimiento de administrador y confirma." + }, + "appPermissions": { + "title": "Agregar permisos de aplicación de SecurityAlert", + "body": "Selecciona Permisos de aplicación y añade SecurityAlert.Read.All y SecurityAlert.ReadWrite.All. Haz clic en Conceder consentimiento de administrador y confirma." + }, + "noteIds": { + "title": "Copiar los IDs de la aplicación", + "body": "Ve a la Información general de la app y copia el ID de aplicación (cliente) y el ID de directorio (inquilino). También necesitas el valor del secreto copiado en el paso 4." + } + }, + "credentialsSection": "Credenciales", + "credentials": { + "title": "Conectar tu tenant de Microsoft 365", + "body": "Introduce los datos de los pasos anteriores. UTMStack verifica las credenciales antes de guardarlas. Puedes añadir múltiples grupos de configuración." + }, + "fields": { + "tenantId": { + "label": "Tenant ID (ID de directorio)" + }, + "clientId": { + "label": "Client ID (ID de aplicación)" + }, + "clientSecret": { + "label": "Secreto de cliente" + }, + "cloudEnv": { + "label": "Entorno de nube (opcional)", + "hint": "Commercial (por defecto), GCC, GCCHigh o DoD" + } + } + }, + "github": { + "source": "GitHub", + "step1": { + "title": "Habilitar el listener de webhook de GitHub en el Collector", + "body": "En el host donde está instalado el Collector, ejecuta este comando para abrir el listener HTTPS de webhook para GitHub:", + "tokenNote": "El terminal imprimirá un token secreto — cópialo inmediatamente. No se volverá a mostrar." + }, + "certWarning": { + "title": "GitHub requiere un certificado TLS firmado por una CA", + "body": "GitHub solo entrega webhooks a endpoints HTTPS con un certificado emitido por una CA pública (los certificados auto-firmados son rechazados). Asegúrate de que el host del Collector tenga un certificado de dominio válido antes de registrar el webhook." + }, + "step2": { + "title": "Registrar el webhook en GitHub", + "body": "En tu repositorio u organización, ve a Settings → Webhooks → Add webhook y completa el formulario:", + "payloadUrl": "Payload URL", + "contentType": "Content type", + "secret": "Secret", + "secretHint": "Pega el token impreso por el Collector en el paso anterior.", + "events": "Which events", + "eventsHint": "Send me everything — o selecciona tipos de eventos específicos." + } + }, + "aix": { + "source": "Servidor AIX", + "step1": { + "title": "Habilitar el listener AIX en el Collector", + "body": "En el host donde está instalado el Collector, ejecuta este comando para abrir el listener de registros AIX:", + "note": "Para usar TCP en lugar de UDP, reemplaza udp por tcp en el comando anterior." + }, + "step2": { + "title": "Configurar AIX para reenviar registros", + "body": "En tu sistema AIX, configura el servicio syslog para redirigir sus registros al host del Collector en el puerto {{port}}. Consulta la documentación de IBM para la sintaxis exacta — varía entre versiones de AIX." + } + }, + "as400": { + "intro": { + "title": "Cómo funciona", + "body": "El Colector AS/400 es un servicio Linux que se conecta directamente a tus sistemas AS/400 (IBM i) y extrae entradas del diario de seguridad, luego las envía de forma segura a UTMStack para correlación y alertas.", + "note": "No se instala nada en el AS/400 — el Colector se ejecuta en un host Linux que tenga acceso de red a tus sistemas AS/400.", + "diagram": { + "source": "tus diarios", + "edge1": "diarios", + "collector": "Colector AS/400", + "collectorSub": "extrae del AS/400", + "edge2": "seguro", + "utmstackSub": "alertas y correlación" + } + }, + "install": { + "title": "Instalar el Colector AS/400", + "body": "Ejecuta este comando en un host Linux que pueda alcanzar tanto UTMStack como tus sistemas AS/400 por la red.", + "reuse": "¿Ya tienes el Colector AS/400 instalado? Omite este paso — solo agrega tus servidores al archivo de configuración en el siguiente paso." + }, + "configure": { + "title": "Agregar tus servidores AS/400", + "body": "Edita as400-config.yaml en el directorio de instalación del colector y agrega cada sistema AS/400 que desees monitorear:", + "note": "Puedes listar múltiples servidores. El colector vigila este archivo y recarga automáticamente al guardar — sin necesidad de reinicio." + }, + "journal": { + "title": "Habilitar el diario de auditoría en AS/400", + "body": "En cada sistema AS/400, asegúrate de que el diario de auditoría de seguridad QAUDJRN esté activo. Consulta la documentación de IBM para los pasos exactos — el procedimiento varía entre versiones de IBM i." + }, + "uninstall": { + "title": "Opcional — Desinstalar el Colector", + "body": "Ejecuta este comando en el host donde está instalado el Colector AS/400 para detener el servicio y eliminar todos los archivos." + } + }, + "bitdefender": { + "intro": { + "title": "Cómo funciona", + "body": "UTMStack se conecta a Bitdefender GravityZone usando tu clave API para configurar el Event Push Service. GravityZone envía entonces los eventos de seguridad directamente a UTMStack para correlación y alertas.", + "diagram": { + "source": "eventos de endpoints", + "edge": "Event Push Service", + "utmstackSub": "alertas y correlación" + }, + "note": "No se instala nada en GravityZone — UTMStack se registra como destino de push usando credenciales de API de solo lectura." + }, + "whitelist": { + "title": "Añadir IPs de Bitdefender a la whitelist", + "body": "Las siguientes IPs de Bitdefender GravityZone deben estar permitidas en tu firewall en el puerto 8000 para que el Event Push Service pueda alcanzar UTMStack:", + "note": "Añade estas IPs a tu firewall o grupo de seguridad antes de completar la configuración." + }, + "apiSection": "Obtener credenciales API", + "api": { + "myAccount": { + "title": "Abrir Mi Cuenta", + "body": "En la consola de Bitdefender GravityZone, haz clic en My Account." + }, + "accessUrl": { + "title": "Anotar la Access URL", + "body": "Desplázate hasta la sección Control Center API y guarda la Access URL — la introducirás en el formulario de credenciales. Luego abre la sección de claves API y haz clic en Add." + }, + "createKey": { + "title": "Crear una clave API", + "body": "Escribe una descripción para la clave API, selecciona la opción Event Push Service API y haz clic en Save. Copia la clave generada." + } + }, + "companySection": "Obtener IDs de empresa", + "company": { + "myCompany": { + "title": "Abrir Mi Empresa", + "body": "En la consola de GravityZone, haz clic en My Company." + }, + "licensing": { + "title": "Anotar los IDs de empresa", + "body": "Abre la sección Licensing y guarda los Company IDs que quieres monitorizar — introdúcelos separados por comas en el formulario de credenciales." + } + }, + "credentials": { + "title": "Introducir credenciales", + "body": "Rellena la Access URL, la clave API, la IP pública de UTMStack (donde GravityZone enviará los eventos) y los IDs de empresa a monitorizar. UTMStack verifica las credenciales antes de guardarlas." + }, + "fields": { + "accessUrl": { + "label": "Access URL de GravityZone" + }, + "connectionKey": { + "label": "Clave API" + }, + "utmPublicIP": { + "label": "IP pública de UTMStack" + }, + "companyIds": { + "label": "IDs de empresa (separados por comas)" + } + } + }, + "netflow": { + "source": "Dispositivo de red", + "step1": { + "title": "Habilitar el listener de NetFlow en el Collector", + "body": "En el host donde está instalado el Collector, ejecuta este comando para abrir el colector NetFlow en el puerto 2055:", + "note": "NetFlow usa solo UDP — TCP y TLS no son compatibles con este protocolo." + }, + "step2": { + "title": "Configurar el dispositivo para exportar NetFlow", + "body": "Apunta la exportación de NetFlow en tu router o firewall al host del Collector en el puerto {{port}} UDP. El ejemplo siguiente es para Cisco IOS — consulta la documentación de tu fabricante para otras plataformas:", + "note": "Reemplaza con el nombre de la interfaz donde se debe monitorizar el tráfico (p.ej. GigabitEthernet0/0). Aplica ingress/egress en cada interfaz relevante." + } + }, + "sophos": { + "intro": { + "title": "Sophos Central — Plugin API", + "body": "Sophos Central proporciona APIs seguras para recuperar datos de eventos y alertas. UTMStack se conecta a esas APIs para centralizar la monitorización y mejorar la visibilidad de seguridad — sin agente ni collector.", + "diagram": { + "source": "API de Sophos Central", + "edge": "HTTPS API", + "utmstackSub": "Ingesta y correlaciona" + }, + "note": "UTMStack consulta la API de Sophos Central periódicamente. Asegúrate de que las credenciales que crees tengan acceso de lectura a eventos y alertas." + }, + "apiSection": "Generar credenciales API en Sophos Central", + "steps": { + "apiCredentials": { + "title": "Abrir la gestión de credenciales API", + "body": "En Sophos Central Admin, navega a Global Settings → API Credentials Management." + }, + "addCredential": { + "title": "Crear una nueva credencial", + "body": "Haz clic en Add Credential. Proporciona un Nombre y una Descripción, selecciona el Rol apropiado y haz clic en Add." + }, + "copyIds": { + "title": "Copiar el Client ID y el Client Secret", + "body": "Copia el Client ID y el Client Secret y guárdalos en un lugar seguro.", + "secretNote": "El Client Secret solo se muestra una vez. Guárdalo antes de cerrar este diálogo." + } + }, + "credentialsSection": "Conectar con UTMStack", + "credentials": { + "title": "Añadir credenciales de Sophos Central", + "body": "Introduce las credenciales que acabas de crear. Puedes añadir más de una cuenta de Sophos haciendo clic en Añadir grupo de configuración." + }, + "fields": { + "clientId": { + "label": "Client ID" + }, + "apiKey": { + "label": "Client Secret / API Key" + } + } + }, + "mikrotik": { + "source": "Router MikroTik", + "step1": { + "title": "Habilitar el listener de MikroTik en el Collector", + "body": "En el host donde está instalado el Collector, ejecuta este comando para abrir el listener syslog de MikroTik:", + "note": "Para usar TCP en lugar de UDP, reemplaza udp por tcp en el comando anterior." + }, + "step2": { + "title": "Configurar MikroTik para reenviar registros", + "body": "En el router MikroTik, crea una acción de logging remota apuntando al host del Collector en el puerto {{port}} y asígnala a los topics relevantes. Ejecuta lo siguiente desde la CLI de RouterOS (Terminal en Winbox):", + "note": "También puedes configurarlo desde Winbox: System → Logging → pestaña Actions (añade una acción Remote) → luego la pestaña Rules (añade reglas apuntando a la nueva acción)." + } + }, + "oracle": { + "source": "Servidor Oracle DB", + "step1": { + "title": "Habilitar la integración de Oracle en el Collector", + "body": "En el servidor donde está instalado el Collector, ejecuta el siguiente comando para comenzar a recibir logs de Oracle:", + "note": "El Collector comenzará a recibir eventos de syslog de Oracle en el puerto 7021." + }, + "step2": { + "title": "Configurar rsyslog en el servidor Oracle", + "body": "Crea el archivo de configuración de rsyslog:", + "editBody": "Abre el archivo con tu editor preferido y añade la siguiente configuración. Reemplaza BASEDIR con la ruta de instalación de Oracle (p. ej., /u01/app/oracle) y con la IP o nombre de host del Collector:", + "note": "Usa @@:7021 en lugar de @ si prefieres entrega por TCP." + }, + "step3": { + "title": "Reiniciar rsyslog", + "body": "Aplica la nueva configuración reiniciando el servicio rsyslog:" + }, + "step4": { + "title": "Validar la configuración", + "body": "Envía mensajes de prueba para verificar que UTMStack está recibiendo eventos de las tres fuentes de logs de Oracle:", + "note": "Abre el Explorador de Logs y busca el texto del mensaje de prueba anterior para confirmar que llegaron." + } + }, + "utmstack": { + "intro": { + "title": "Cómo funciona", + "body": "Esta integración automonitoriza tu despliegue de UTMStack. Un colector ligero instalado en el host de UTMStack lee los logs de los propios contenedores Docker de la plataforma y los envía de vuelta a UTMStack para correlación y alertas.", + "diagram": { + "source": "Logs de Docker", + "sourceSub": "Contenedores de UTMStack", + "edge1": "lee", + "collector": "Colector", + "collectorSub": "en el host", + "edge2": "ingesta", + "utmstackSub": "Correlaciona y alerta" + } + }, + "requirements": { + "title": "Solo se ejecuta en el host de UTMStack", + "body": "Esta integración solo se puede instalar en una instancia de UTMStack que ejecute Ubuntu o una distribución de la familia Red Hat. Instala el colector directamente en el servidor de UTMStack." + }, + "install": { + "title": "Instalar el colector", + "body": "En el host de UTMStack, elige tu sistema operativo y ejecuta el comando siguiente para descargar e instalar el colector de automonitorización:", + "sensitiveWarning": "Este comando contiene un token de conexión sensible. Trátalo como una contraseña y no lo compartas." + }, + "after": { + "title": "Qué verás después de instalar", + "item1": "El colector se registra y aparece en Fuentes de datos.", + "item2": "Los logs de los contenedores de UTMStack empiezan a fluir en menos de un minuto.", + "item3": "Los eventos se pueden buscar en el Explorador de Logs bajo el tipo de dato utmstack." + }, + "uninstall": { + "title": "Desinstalar el colector", + "body": "Para eliminar el colector de automonitorización del host de UTMStack, ejecuta:" + } + }, + "endpoint": { + "title": "Detalles de conexión", + "hint": "Configure {{name}} para reenviar sus registros al Collector usando el host y el puerto indicados a continuación." + }, + "syslog": { + "sections": { + "sendLogs": { + "title": "1 · Enviar registros a UTMStack", + "body": "Configure su dispositivo para enviar mensajes syslog por UDP (514) o TCP (514) al agente de UTMStack." + }, + "enableCollector": { + "title": "2 · Habilitar el colector syslog", + "body": "Habilite el colector de registros y la integración syslog en el archivo de configuración donde está instalado su agente de UTMStack." + }, + "activate": { + "title": "3 · Activar", + "body": "Active el módulo de UTMStack para que los eventos comiencen a fluir en el Log Explorer." + } + } + }, + "vmware": { + "source": "VMware ESXi", + "step1": { + "title": "Habilitar el listener de VMware en el Collector", + "body": "En el host donde está instalado el Collector, ejecute este comando para abrir el listener syslog de VMware ESXi. ESXi transmite por TCP:", + "note": "Para un canal cifrado use tls en lugar de tcp (cargue primero los certificados en el Collector)." + }, + "step2": { + "title": "Apuntar el syslog de ESXi al Collector", + "body": "Abra una sesión SSH/ESXi Shell en el host (o use el vSphere Client: Host → Configure → Advanced System Settings → Syslog.global.logHost). Establezca el loghost remoto en {{host}}:{{port}} y recargue la configuración:", + "note": "En vSphere puede en cambio establecer Syslog.global.logHost con el mismo valor tcp://host:port en lugar de ejecutar esxcli." + }, + "step3": { + "title": "Abrir el firewall de ESXi para syslog", + "body": "Permita el syslog saliente a través del firewall de ESXi para que el host pueda llegar al Collector:" + } + }, + "eset": { + "source": "ESET Protect", + "step1": { + "title": "Habilitar el listener de ESET en el Collector", + "body": "En el host donde está instalado el Collector, ejecute este comando para abrir el listener syslog de ESET:", + "note": "Para usar TCP en lugar de UDP, reemplace udp por tcp en el comando anterior." + }, + "console": { + "moreMenu": { + "title": "Abrir el menú More", + "body": "En la barra lateral de la consola ESET Protect, haga clic en el menú More." + }, + "serverConfig": { + "title": "Abrir la configuración del servidor", + "body": "En More, abra la sección Server settings (Server configuration)." + }, + "advanced": { + "title": "Expandir la configuración avanzada", + "body": "Haga clic en Advanced settings para expandir la lista completa de opciones de configuración." + }, + "syslog": { + "title": "Configurar el servidor Syslog", + "body": "Desplácese hasta Syslog server, habilite Export logs to Syslog y establezca el destino en el host del Collector en el puerto {{port}} (UDP). ESET envía LEEF/syslog, que el Collector ingiere como el tipo de datos antivirus-esmc-eset." + } + } + }, + "kaspersky": { + "source": "Kaspersky Security", + "step1": { + "title": "Habilitar el listener de Kaspersky en el Collector", + "body": "En el host donde está instalado el Collector, ejecute este comando para abrir el listener syslog de Kaspersky:", + "note": "Para usar TCP en lugar de UDP, reemplace udp por tcp en el comando anterior." + }, + "console": { + "consoleSettings": { + "title": "Abrir Console settings → Integration", + "body": "En la barra lateral del Kaspersky Security Center, abra Console settings y haga clic en el submenú Integration." + }, + "siem": { + "title": "Abrir la configuración de integración SIEM", + "body": "En Integration, seleccione SIEM y haga clic en el enlace Settings para abrir la configuración de exportación." + }, + "configure": { + "title": "Configurar la exportación SIEM", + "body": "Habilite la exportación y configure Kaspersky para enviar eventos en formato Splunk (CEF) al host del Collector en el puerto {{port}} (UDP). El Collector los ingiere como el tipo de datos antivirus-kaspersky." + } + } + }, + "webroot": { + "sections": { + "login": { + "title": "1 · Iniciar sesión en la consola de administración", + "body": "Inicie sesión en la consola de administración de Webroot. Se abre en la pestaña Sites." + }, + "openSettings": { + "title": "2 · Abrir Settings", + "body": "Haga clic en la pestaña Settings." + }, + "apiAccess": { + "title": "3 · Abrir API Access", + "body": "Desde la pestaña Subscriptions, haga clic en la pestaña API Access." + }, + "createCredential": { + "title": "4 · Crear una credencial de cliente", + "body": "Haga clic en New y complete el Name y la Description. Lea el acuerdo de SecureAnywhere Business Solution y Unity API, luego haga clic en Create." + }, + "noteClientSecret": { + "title": "5 · Copiar el ID de cliente y el secreto", + "body": "Guarde el Client ID de la lista y el Client Secret que se muestra solo una vez. Haga clic en \"I have made note of the client secret\" para confirmar." + }, + "fillForm": { + "title": "6 · Completar el formulario", + "body": "Proporcione el client ID y el client secret a UTMStack. Puede agregar más de un grupo de configuración de Webroot si es necesario." + }, + "activate": { + "title": "7 · Activar", + "body": "Active el módulo de UTMStack para que los eventos de Webroot comiencen a fluir." + } + } + }, + "sentinelOne": { + "source": "SentinelOne", + "step1": { + "title": "Habilitar el listener de SentinelOne en el Collector", + "body": "En el host donde está instalado el Collector, ejecute este comando para abrir el listener syslog de SentinelOne. SentinelOne transmite CEF por TCP:", + "note": "Para un canal cifrado use tls en lugar de tcp (cargue primero los certificados en el Collector)." + }, + "console": { + "settings": { + "title": "Abrir la configuración de SentinelOne", + "body": "En la barra lateral de la consola de administración de SentinelOne, haga clic en el menú Settings." + }, + "syslog": { + "title": "Configurar la integración Syslog", + "body": "Vaya a Integrations → Syslog y habilítelo. Establezca el host en {{host}} y el puerto en {{port}}, mantenga el formato como CEF, haga clic en Test para verificar la conexión, luego Save." + } + } + }, + "salesforce": { + "sections": { + "openSetup": { + "title": "1 · Abrir Setup", + "body": "Vaya a Setup y seleccione \"Setup for the current app\" en la parte superior derecha de la pantalla." + }, + "appManager": { + "title": "2 · Abrir App Manager", + "body": "Escriba \"App Manager\" en el cuadro de búsqueda rápida y seleccione App Manager." + }, + "newConnectedApp": { + "title": "3 · Crear una nueva Connected App", + "body": "En la pantalla del Lightning Experience App Manager, haga clic en \"New Connected App\" y complete los campos." + }, + "oauthSettings": { + "title": "4 · Habilitar OAuth Settings", + "body": "En la sección \"API (Enable OAuth Settings)\", marque \"Enable OAuth Settings\" y use https://login.salesforce.com/services/oauth2/success como Callback URL." + }, + "oauthScopes": { + "title": "5 · Agregar OAuth scopes", + "body": "Seleccione \"Access Connect REST API resources (chatter_api)\" en Selected OAuth Scopes." + }, + "save": { + "title": "6 · Guardar", + "body": "Guarde los cambios y seleccione Continue en la siguiente pantalla." + }, + "manageConsumer": { + "title": "7 · Abrir Manage Consumer Details", + "body": "Dentro de su Connected App, vaya a \"API (Enable OAuth Settings)\" y haga clic en \"Manage Consumer Details\" junto a Consumer Key and Secret." + }, + "copyCredentials": { + "title": "8 · Copiar la clave y el secreto del consumidor", + "body": "Verifique su identidad. El Consumer Key y el Consumer Secret aparecen en \"Consumer Details\". Cópielos con el botón Copy." + }, + "fillForm": { + "title": "9 · Completar el formulario", + "body": "Proporcione el Consumer Key, Consumer Secret, nombre de usuario y contraseña de Salesforce a UTMStack." + }, + "activate": { + "title": "10 · Activar", + "body": "Active el módulo de UTMStack para que los eventos de Salesforce comiencen a fluir." + } + } + }, + "iis": { + "sections": { + "enableModule": { + "title": "1 · Habilitar el módulo IIS de Filebeat", + "body": "En el host del agente de UTMStack, ejecute:\ncd \"C:\\Program Files\\UTMStack\\UTMStack Agent\\beats\\filebeat\\\" && filebeat modules enable iis" + }, + "configureModule": { + "title": "2 · Configurar el módulo IIS", + "body": "Edite C:\\Program Files\\UTMStack\\UTMStack Agent\\beats\\filebeat\\modules.d\\iis.yml como se muestra a continuación para apuntar a los directorios de registros IIS que desea enviar." + }, + "activate": { + "title": "3 · Activar", + "body": "Active el módulo de UTMStack para que los eventos de IIS comiencen a fluir." + } + } + }, + "filebeat": { + "sections": { + "installRsyslog": { + "title": "1 · Instalar rsyslog", + "body": "Asegúrese de que rsyslog esté instalado en el host. Use el gestor de paquetes de su distribución (apt, dnf, yum)." + }, + "configureRsyslog": { + "title": "2 · Configurar rsyslog para reenviar a UTMStack", + "body": "Edite /etc/rsyslog.conf (o un archivo en /etc/rsyslog.d/) y añada una regla de reenvío que apunte al agente UTMStack por UDP o TCP en el puerto 514." + }, + "restartRsyslog": { + "title": "3 · Reiniciar rsyslog", + "body": "Reinicie el servicio rsyslog: sudo systemctl restart rsyslog" + }, + "enableCollector": { + "title": "4 · Habilitar el colector de logs de Linux", + "body": "Habilite el colector de logs y la integración Linux Logs en el archivo de configuración donde está instalado el agente UTMStack." + } + } + }, + "json": { + "sections": { + "overview": { + "title": "1 · Usar el endpoint de ingesta HTTP/JSON", + "body": "UTMStack acepta eventos JSON arbitrarios por HTTPS. Envíe una solicitud POST con una lista de eventos; UTMStack los analiza y los enruta a través del parser configurado." + }, + "auth": { + "title": "2 · Autenticarse con un token de federación", + "body": "Obtenga un token de federación desde Configuración → Connection Key y envíelo como Bearer token en el encabezado Authorization." + } + }, + "endpoint": { + "title": "Endpoint de ingesta JSON", + "hint": "Use este formato de solicitud desde su aplicación o un cron job. El token es la clave de federación de Configuración → Connection Key." + } + }, + "ldap": { + "sections": { + "openServerManager": { + "title": "1 · Abrir Server Manager", + "body": "En el controlador de dominio AD, abra Server Manager." + }, + "addRoles": { + "title": "2 · Agregar roles y características", + "body": "Elija \"Agregar roles y características\" desde el menú Manage." + }, + "selectCertServices": { + "title": "3 · Seleccionar Active Directory Certificate Services", + "body": "En el paso Server Roles, seleccione Active Directory Certificate Services." + }, + "installServices": { + "title": "4 · Instalar el servicio de rol Certificate Authority", + "body": "En el paso Role Services, seleccione Certificate Authority y complete el asistente." + }, + "configureAdCs": { + "title": "5 · Configurar AD CS", + "body": "Tras la instalación, haga clic en la notificación para configurar AD CS y elija Certificate Authority como servicio de rol a configurar." + }, + "pickCaType": { + "title": "6 · Seleccionar el tipo de CA", + "body": "Elija Enterprise CA → Root CA → Create a new private key." + }, + "setValidity": { + "title": "7 · Establecer el período de validez del certificado", + "body": "Establezca un período de validez adecuado para su organización (5 años es lo habitual)." + }, + "confirm": { + "title": "8 · Confirmar e instalar", + "body": "Revise la configuración y haga clic en Configure para finalizar." + }, + "restart": { + "title": "9 · Reiniciar el controlador de dominio", + "body": "Reinicie el controlador de dominio para que LDAPS quede disponible en TCP 636." + }, + "activate": { + "title": "10 · Activar", + "body": "Active el módulo UTMStack para que los eventos de auditoría de AD comiencen a fluir." + } + } + }, + "vulnerabilities": { + "sections": { + "overview": { + "title": "1 · Acerca del escáner de vulnerabilidades", + "body": "El módulo de vulnerabilidades de UTMStack analiza los activos descubiertos a través del módulo Asset Management y compara su huella digital con la base de datos CVE." + }, + "scope": { + "title": "2 · Definir el alcance del escaneo", + "body": "Use el módulo Asset Management para registrar los hosts que desea escanear. El escáner de vulnerabilidades se ejecutará periódicamente sobre ellos." + }, + "activate": { + "title": "3 · Activar", + "body": "Active el módulo UTMStack para comenzar el escaneo." + } + } + }, + "assetScanner": { + "sections": { + "overview": { + "title": "1 · Acerca de Asset Management", + "body": "El módulo Asset Management descubre e inventaría hosts, software y servicios en su red." + }, + "agentRequirement": { + "title": "2 · Requisito del agente", + "body": "El descubrimiento de activos utiliza agentes UTMStack que se ejecutan en hosts Linux, Windows o macOS. Instale el agente en los sistemas que desee inventariar." + }, + "activate": { + "title": "3 · Activar", + "body": "Active el módulo UTMStack para iniciar el descubrimiento de activos." + } + } + }, + "fileIntegrity": { + "sections": { + "enableAuditPolicy": { + "title": "1 · Habilitar la auditoría de acceso a objetos", + "body": "En el host Windows, abra Group Policy → Computer Configuration → Windows Settings → Security Settings → Advanced Audit Policy Configuration → Object Access y habilite \"Audit File System\"." + }, + "configureFolderAuditing": { + "title": "2 · Configurar la auditoría de carpetas", + "body": "En cada carpeta que desee monitorear, abra Propiedades → Security → Advanced → Auditing y añada una entrada de auditoría para los principales y tipos de acceso que le interesen." + }, + "verifyEvents": { + "title": "3 · Verificar que los eventos aparecen en el log de Seguridad", + "body": "Abra Event Viewer y confirme que se generan eventos 4663/4670 cuando se accede a los objetos auditados." + }, + "activate": { + "title": "4 · Activar", + "body": "Active el módulo UTMStack para que los eventos de integridad de archivos comiencen a fluir." + } + } + }, + "socAi": { + "sections": { + "overview": { + "title": "1 · Acerca de SOC AI", + "body": "SOC AI amplía UTMStack con un analista respaldado por LLM que resume alertas y sugiere los próximos pasos. Se ejecuta con el proveedor que configure." + }, + "chooseProvider": { + "title": "2 · Elegir un proveedor", + "body": "Seleccione un proveedor: OpenAI, Anthropic, Azure OpenAI, Google Gemini, Ollama, Mistral, DeepSeek, Groq o un endpoint personalizado compatible con OpenAI." + }, + "configureCredentials": { + "title": "3 · Configurar credenciales", + "body": "Proporcione la API key y (cuando corresponda) el nombre del modelo y la URL del endpoint." + }, + "activate": { + "title": "4 · Activar", + "body": "Active el módulo UTMStack para que SOC AI comience a trabajar con las alertas." + } + } + }, + "windowsFaa": { + "sections": { + "enableAuditPolicy": { + "title": "1 · Habilitar la auditoría de acceso a objetos", + "body": "En el host Windows, abra Group Policy → Computer Configuration → Windows Settings → Security Settings → Advanced Audit Policy Configuration → Object Access y habilite \"Audit File System\"." + }, + "configureFolderAuditing": { + "title": "2 · Configurar la auditoría de carpetas", + "body": "En cada carpeta que desee monitorear, abra Propiedades → Security → Advanced → Auditing y añada una entrada de auditoría para los principales y tipos de acceso que le interesen." + }, + "activate": { + "title": "3 · Activar", + "body": "Active el módulo UTMStack para que los eventos de actividad de archivos comiencen a fluir." + } + } + }, + "awsBeanstalk": { + "sections": { + "openConsole": { + "title": "1 · Abrir la consola de Elastic Beanstalk", + "body": "En la consola de AWS, abra Elastic Beanstalk." + }, + "environment": { + "title": "2 · Abrir la página de administración del entorno", + "body": "Navegue a la página de administración del entorno que desea monitorear." + }, + "configuration": { + "title": "3 · Abrir Configuración", + "body": "Seleccione Configuration." + }, + "software": { + "title": "4 · Modificar la configuración de Software", + "body": "En la categoría Software configuration, seleccione Modify." + }, + "s3LogStorage": { + "title": "5 · Habilitar el almacenamiento de logs en S3", + "body": "En S3 log storage, seleccione Rotate logs para subir los logs rotados a Amazon S3." + }, + "cloudwatchStreaming": { + "title": "6 · Habilitar la transmisión de CloudWatch Logs", + "body": "En Instance log streaming to CloudWatch Logs, habilite la transmisión, establezca el período de retención y elija si desea subir los logs existentes." + }, + "activate": { + "title": "7 · Activar", + "body": "Active el módulo UTMStack para que los eventos de Beanstalk comiencen a fluir." + } + } + }, + "awsFargate": { + "sections": { + "taskDefinition": { + "title": "1 · Actualizar la definición de tarea", + "body": "En la definición de tarea del Fargate, establezca el logDriver en \"awslogs\" y defina el nombre del grupo de logs." + }, + "cloudwatchLogs": { + "title": "2 · Confirmar que CloudWatch Logs está recibiendo logs", + "body": "Abra la consola de CloudWatch Logs y confirme que el grupo de logs se está llenando cuando se ejecutan las tareas." + }, + "iamPrerequisite": { + "title": "3 · Requisito previo del usuario IAM", + "body": "Esta integración comparte credenciales con el módulo AWS IAM User; asegúrese de que esté configurado con CloudWatchLogsReadOnlyAccess." + }, + "activate": { + "title": "4 · Activar", + "body": "Active el módulo UTMStack para que los eventos de Fargate comiencen a fluir." + } + } + }, + "awsIamUser": { + "sections": { + "iamConsole": { + "title": "1 · Abrir la consola de IAM", + "body": "En la consola de AWS, vaya a IAM → Users → Add users." + }, + "createUser": { + "title": "2 · Crear el usuario", + "body": "Elija un nombre de usuario (por ejemplo, utmstack-ingest). Seleccione acceso programático." + }, + "programmaticAccess": { + "title": "3 · Establecer el tipo de credencial", + "body": "Seleccione \"Access key — Programmatic access\"." + }, + "attachPolicy": { + "title": "4 · Adjuntar la política de lectura de CloudWatch", + "body": "Adjunte la política administrada por AWS CloudWatchLogsReadOnlyAccess." + }, + "review": { + "title": "5 · Revisar el usuario", + "body": "Revise los detalles del usuario y haga clic en Create user." + }, + "copyKeys": { + "title": "6 · Copiar el ID de clave de acceso y el secreto", + "body": "Copie el Access key ID y la Secret access key; el secreto se muestra una sola vez." + }, + "createLogGroup": { + "title": "7 · Crear un grupo de logs en CloudWatch", + "body": "En CloudWatch → Log groups, crea un grupo de logs llamado \"utmstack\" — otras integraciones de AWS lo usarán como destino." + }, + "fillForm": { + "title": "8 · Completar el formulario", + "body": "Proporciona la clave de acceso, el secreto, la región predeterminada y el nombre del grupo de logs (p. ej. \"utmstack\") a UTMStack." + }, + "activate": { + "title": "9 · Activar", + "body": "Activa el módulo de UTMStack para que los eventos de AWS comiencen a fluir." + } + } + }, + "awsLambda": { + "sections": { + "iamPrerequisite": { + "title": "1 · Requisito previo: usuario IAM", + "body": "Lambda depende del módulo AWS IAM User — asegúrate de que esa integración esté configurada primero con CloudWatchLogsReadOnlyAccess." + }, + "cloudwatchStream": { + "title": "2 · Lambda ya transmite a CloudWatch Logs", + "body": "AWS Lambda publica automáticamente los logs de ejecución en CloudWatch Logs bajo /aws/lambda/. UTMStack los ingiere desde el grupo de logs que configuraste en la configuración del usuario IAM." + }, + "activate": { + "title": "3 · Activar", + "body": "Activa el módulo de UTMStack para que los eventos de Lambda comiencen a fluir." + } + } + }, + "awsSqlServer": { + "sections": { + "openRds": { + "title": "1 · Abrir la consola de Amazon RDS", + "body": "Abre https://console.aws.amazon.com/rds/." + }, + "pickDb": { + "title": "2 · Seleccionar la instancia de BD", + "body": "En el panel de navegación, selecciona Databases y elige la instancia de BD que deseas supervisar." + }, + "modify": { + "title": "3 · Modificar la instancia", + "body": "Haz clic en Modify." + }, + "logExports": { + "title": "4 · Habilitar exportación de logs", + "body": "En la sección Log exports, selecciona Error log y Agent log para publicarlos en CloudWatch Logs." + }, + "apply": { + "title": "5 · Aplicar cambios", + "body": "Haz clic en Continue y luego en Modify DB Instance en la página de resumen." + }, + "activate": { + "title": "6 · Activar", + "body": "Activa el módulo de UTMStack para que los eventos de SQL Server comiencen a fluir." + } + } + }, + "awsPostgresql": { + "sections": { + "openRds": { + "title": "1 · Abrir la consola de Amazon RDS", + "body": "Abre https://console.aws.amazon.com/rds/." + }, + "pickDb": { + "title": "2 · Seleccionar la instancia de BD", + "body": "En el panel de navegación, selecciona Databases y elige la instancia de BD que deseas modificar." + }, + "logExports": { + "title": "3 · Habilitar exportación de logs", + "body": "En la sección Log exports, selecciona el log de PostgreSQL para publicarlo en CloudWatch Logs." + }, + "apply": { + "title": "4 · Aplicar cambios", + "body": "Haz clic en Continue y luego en Modify DB Instance en la página de resumen." + }, + "activate": { + "title": "5 · Activar", + "body": "Activa el módulo de UTMStack para que los eventos de PostgreSQL comiencen a fluir." + } + } + }, + "awsTrafficMirror": { + "sections": { + "createTarget": { + "title": "1 · Crear un destino de duplicación de tráfico", + "body": "En la consola de VPC, crea un Traffic Mirror Target que apunte a la interfaz de red de la VM del agente UTMStack." + }, + "createFilter": { + "title": "2 · Crear un filtro de duplicación de tráfico", + "body": "Crea un Traffic Mirror Filter y agrega reglas de entrada/salida para los protocolos que deseas duplicar (p. ej. todo TCP, todo UDP)." + }, + "createSession": { + "title": "3 · Crear una sesión de duplicación de tráfico", + "body": "Crea una Traffic Mirror Session que empareje cada interfaz de red de origen con el destino y el filtro que creaste." + }, + "iamPrerequisite": { + "title": "4 · Requisito previo: usuario IAM", + "body": "Asegúrate de que el módulo AWS IAM User también esté configurado para que UTMStack pueda leer los logs de flujo de VPC si es necesario." + }, + "activate": { + "title": "5 · Activar", + "body": "Activa el módulo de UTMStack para que el tráfico duplicado comience a procesarse." + } + } + }, + "deceptivebytes": { + "source": "Deceptive Bytes", + "step1": { + "title": "Habilitar el listener de Deceptive Bytes en el Collector", + "body": "En el host donde está instalado el Collector, ejecuta este comando para abrir el listener syslog de Deceptive Bytes:", + "note": "Para usar TCP en lugar de UDP, reemplaza udp por tcp en el comando anterior." + }, + "step2": { + "title": "Configurar Deceptive Bytes para reenviar logs", + "body": "En la consola de administración de Deceptive Bytes, configura el reenvío syslog para enviar eventos al host del Collector en el puerto {{port}} (UDP). Deceptive Bytes emite syslog en formato CEF, que el Collector ingiere como tipo de datos deceptive-bytes." + } + }, + "fortigate": { + "source": "Firewall FortiGate", + "step1": { + "title": "Habilitar el listener de FortiGate en el Collector", + "body": "En el host donde está instalado el Collector, ejecuta este comando para abrir el listener syslog de FortiGate:", + "note": "Para usar TCP en lugar de UDP, reemplaza udp por tcp en el comando anterior." + }, + "step2": { + "title": "Configurar FortiGate para reenviar logs", + "body": "En el FortiGate, apunta el syslog al host del Collector en el puerto {{port}}. Ejecuta lo siguiente desde el CLI de FortiOS (o usa Log & Report → Log Settings → Syslog en la interfaz gráfica):", + "note": "Reemplaza la dirección del servidor si el Collector se ejecuta en un host diferente. Para múltiples colectores syslog, usa syslogd2/syslogd3/syslogd4." + } + }, + "fortiweb": { + "source": "FortiWeb WAF", + "step1": { + "title": "Habilitar el listener de FortiWeb en el Collector", + "body": "En el host donde está instalado el Collector, ejecuta este comando para abrir el listener syslog de FortiWeb:", + "note": "Para usar TCP en lugar de UDP, reemplaza udp por tcp en el comando anterior." + }, + "step2": { + "title": "Configurar FortiWeb para reenviar logs", + "body": "En el FortiWeb, crea una política syslog que apunte al host del Collector en el puerto {{port}} y habilita el registro syslog. Ejecuta lo siguiente desde el CLI de FortiWeb (o usa Log & Report → Log Policy → Syslog Policy en la interfaz gráfica):", + "note": "Asegúrate de que los tipos de log relevantes (Attack, Event, Traffic) estén habilitados para enviarse a syslog en la configuración de Log & Report." + } + }, + "paloalto": { + "source": "Firewall Palo Alto", + "step1": { + "title": "Habilitar el listener de Palo Alto en el Collector", + "body": "En el host donde está instalado el Collector, ejecuta este comando para abrir el listener syslog de Palo Alto:", + "note": "Para usar TCP en lugar de UDP, reemplaza udp por tcp en el comando anterior." + }, + "step2": { + "title": "Crear un perfil de servidor Syslog", + "body": "En PAN-OS, ve a Device → Server Profiles → Syslog y agrega un perfil. Establece la dirección del servidor en {{host}}, transporte UDP, puerto {{port}} y formato BSD." + }, + "step3": { + "title": "Reenviar logs y confirmar", + "body": "Crea un perfil de Log Forwarding (Objects → Log Forwarding) que envíe los tipos de log Traffic, Threat y otros al perfil syslog anterior, asígnalo a las reglas de Security policy (Policies → Security → rule → Actions → Log Forwarding) y luego haz Commit." + } + }, + "pfsense": { + "source": "Firewall pfSense", + "step1": { + "title": "Habilitar el listener de pfSense en el Collector", + "body": "En el host donde está instalado el Collector, ejecuta este comando para abrir el listener syslog de pfSense:", + "note": "Para usar TCP en lugar de UDP, reemplaza udp por tcp en el comando anterior." + }, + "step2": { + "title": "Habilitar el registro remoto en pfSense", + "body": "En la interfaz web de pfSense, ve a Status → System Logs → Settings. En Remote Logging Options, marca Enable Remote Logging, establece un servidor de log remoto en {{host}}:{{port}}, elige qué logs enviar (o Everything) y haz clic en Save." + } + }, + "sonicwall": { + "source": "Firewall SonicWall", + "step1": { + "title": "Habilitar el listener de SonicWall en el Collector", + "body": "En el host donde está instalado el Collector, ejecuta este comando para abrir el listener syslog de SonicWall:", + "note": "Para usar TCP en lugar de UDP, reemplaza udp por tcp en el comando anterior." + }, + "step2": { + "title": "Agregar un servidor Syslog en SonicOS", + "body": "En SonicOS, ve a Device → Log → Syslog (Manage → Log → Syslog en firmware más antiguo) y agrega un Syslog Server con dirección {{host}} y puerto {{port}}. Establece el Syslog Format en ArcSight (CEF) — UTMStack analiza SonicWall en CEF — y haz clic en Apply." + } + }, + "sophosxg": { + "source": "Sophos Firewall", + "step1": { + "title": "Habilitar el listener de Sophos Firewall en el Collector", + "body": "En el host donde está instalado el Collector, ejecuta este comando para abrir el listener syslog de Sophos Firewall:", + "note": "Para usar TCP en lugar de UDP, reemplaza udp por tcp en el comando anterior." + }, + "step2": { + "title": "Agregar un servidor Syslog en Sophos Firewall", + "body": "En la consola de Sophos Firewall (SFOS), ve a System → System services → Log settings y agrega un Syslog Server con dirección {{host}} y puerto {{port}}. Elige los tipos de log que deseas reenviar (firewall, IPS, ATP, web, etc.) y haz clic en Apply." + } + }, + "suricata": { + "source": "Suricata IDS", + "step1": { + "title": "Habilitar el listener de Suricata en el Collector", + "body": "En el host donde está instalado el Collector, ejecuta este comando para abrir el listener de Suricata:", + "note": "Para usar TCP en lugar de UDP, reemplaza udp por tcp en el comando anterior." + }, + "step2": { + "title": "Enviar logs EVE de Suricata a syslog", + "body": "Suricata se ingiere como JSON (EVE). En el host de Suricata, edita suricata.yaml y configura la salida eve-log para escribir en syslog:", + "note": "Luego reinicia Suricata: sudo systemctl restart suricata" + }, + "step3": { + "title": "Reenviar syslog al Collector", + "body": "Apunta la facilidad local5 (donde Suricata escribe ahora) al Collector. Agrega esta regla en /etc/rsyslog.d/60-utmstack-suricata.conf en el host de Suricata:", + "note": "Usa @@ en lugar de @ para TCP. Luego reinicia rsyslog: sudo systemctl restart rsyslog" + } + }, + "o365_graph": { + "intro": { + "title": "Cómo funciona", + "body": "UTMStack se conecta a Microsoft 365 con una app registrada en Azure AD y consulta Microsoft Graph por eventos de seguridad: alertas, incidentes, auditoría de directorio, sign-ins, detecciones de riesgo, hunting queries y auditoría de Purview. No se instala ningún agente en el tenant.", + "diagram": { + "source": "eventos de seguridad", + "edge": "Microsoft Graph", + "utmstackSub": "correlación & alertas" + }, + "note": "UTMStack requiere solo acceso de lectura a la API de Graph — no se piden permisos de escritura." + }, + "appSection": "Registro de la app en Azure", + "steps": { + "azurePortal": { + "title": "Abrir Microsoft Entra ID", + "body": "Abrí el portal de Azure (portal.azure.com) y hacé clic en Microsoft Entra ID." + }, + "appRegistrations": { + "title": "Ir a App registrations", + "body": "En el menú izquierdo, hacé clic en App registrations." + }, + "registerApp": { + "title": "Registrar una app nueva", + "body": "Hacé clic en New registration. Nombrala UTMStack Graph Dev, elegí Accounts in this organizational directory only (Single-tenant) y hacé clic en Register." + }, + "clientSecret": { + "title": "Crear un client secret", + "body": "Andá a Certificates & Secrets → New client secret. Agregá una descripción, poné la expiración en 730 días (24 meses) y hacé clic en Add.", + "copyNote": "Copiá el valor del secret de inmediato — solo se muestra una vez y no se puede recuperar después." + }, + "apiPermissions": { + "title": "Agregar permisos de Microsoft Graph", + "body": "Andá a API Permissions → Add a permission y elegí Microsoft Graph, luego Application permissions." + }, + "graphPermissions": { + "title": "Agregar las cuatro permissions de Graph", + "body": "Agregá SecurityEvents.Read.All, Directory.Read.All, AuditLog.Read.All y IdentityRiskEvent.Read.All." + }, + "adminConsent": { + "title": "Dar admin consent", + "body": "De vuelta en API Permissions, hacé clic en Grant admin consent y confirmá." + }, + "noteIds": { + "title": "Copiar los IDs de la app", + "body": "Andá a Overview de la app y copiá el Application (client) ID y el Directory (tenant) ID. También necesitás el valor del secret que copiaste en el paso 4." + } + }, + "credentialsSection": "Credenciales", + "credentials": { + "title": "Conectar tu tenant de Microsoft 365", + "body": "Ingresá los datos de los pasos anteriores. UTMStack verifica las credenciales antes de guardar. Podés agregar varios grupos de configuración." + }, + "fields": { + "tenantId": { + "label": "Tenant ID (Directory ID)" + }, + "clientId": { + "label": "Client ID (Application ID)" + }, + "clientSecret": { + "label": "Client Secret" + }, + "cloudEnv": { + "label": "Cloud Environment (opcional)", + "hint": "Commercial (default), GCC, GCCHigh o DoD" + } + } + } + }, + "cloud": { + "howItWorksTitle": "Cómo funciona", + "howItWorksBody": "{{name}} se ejecuta completamente dentro de UTMStack — no hay agente ni colector que desplegar. Proporciona credenciales de API de solo lectura y UTMStack extraerá eventos en un horario, los analizará y los ingerirá en Log Explorer.", + "connectionTitle": "Conexión", + "noFields": "No hay campos de conexión configurados.", + "testConnection": "Probar conexión", + "save": "Guardar", + "afterTitle": "Qué verás después de conectar", + "after1": "UTMStack realiza un relleno inicial de eventos recientes.", + "after2": "Desde entonces, los eventos se extraen cada 1–5 minutos (depende de la API).", + "after3": "La integración aparece bajo Fuentes de datos con el estado actual de extracción y retraso.", + "tenants": { + "title": "Grupos de configuración configurados", + "empty": "Aún no hay grupos de configuración. Añade el primero más abajo.", + "loading": "Cargando grupos de configuración…", + "nameLabel": "Nombre del grupo de configuración", + "namePlaceholder": "p. ej. acme-prod", + "add": "Añadir grupo de configuración", + "update": "Actualizar grupo de configuración", + "delete": "Eliminar", + "edit": "Editar", + "cancel": "Cancelar", + "editing": "Editando: {{name}}", + "selectFile": "Seleccionar archivo", + "replaceFile": "Reemplazar archivo", + "fileLoaded": "Archivo cargado", + "invalidJson": "No se pudo procesar el archivo como JSON.", + "createError": "No se pudo crear el grupo de configuración. Inténtalo de nuevo.", + "updateError": "No se pudo actualizar el grupo de configuración. Inténtalo de nuevo.", + "createSuccess": "Grupo de configuración creado correctamente.", + "updateSuccess": "Grupo de configuración actualizado correctamente." + }, + "google": { + "sections": { + "createTopic": { + "title": "1 · Crea un tema de Pub/Sub", + "body": "En la consola de Google Cloud, abre Pub/Sub → Temas y crea un nuevo tema. UTMStack recibirá eventos a través de este tema.", + "docLabel": "Abrir la página de topics de Pub/Sub" + }, + "createSubscription": { + "title": "2 · Crea una suscripción", + "body": "Dentro del tema, crea una suscripción de tipo Pull. UTMStack obtendrá los mensajes desde esta suscripción." + }, + "configureSubscription": { + "title": "3 · Configura la suscripción", + "body": "Establece la duración de retención de mensajes según tu tolerancia a interrupciones (7 días por defecto está bien). Deja el plazo de confirmación en 10 segundos y la expiración en «Nunca expirar»." + }, + "logsRouter": { + "title": "4 · Abre Logs Router", + "body": "Navega a Logging → Logs Router y crea un nuevo sink. Esto reenvía los logs del proyecto al tema de Pub/Sub creado arriba." + }, + "sinkDestination": { + "title": "5 · Apunta el sink al tema", + "body": "Elige Tema de Cloud Pub/Sub como destino del sink y selecciona el tema que creaste. Usa filtros de inclusión/exclusión para acotar lo que se reenvía." + }, + "serviceAccount": { + "title": "6 · Crea una cuenta de servicio", + "body": "Abre IAM y administración → Cuentas de servicio y crea una nueva cuenta de servicio. Asígnale el rol Editor de Pub/Sub para que UTMStack pueda leer desde la suscripción.", + "docLabel": "Abrir la página de cuentas de servicio" + }, + "serviceAccountKey": { + "title": "7 · Genera una clave para la cuenta de servicio", + "body": "Abre la cuenta de servicio, ve a la pestaña Claves y añade una nueva clave. Selecciona JSON como tipo de clave." + }, + "downloadKey": { + "title": "8 · Descarga y carga la clave JSON", + "body": "Guarda el archivo JSON que Google descarga: su contenido va en el campo «Clave JSON de cuenta de servicio» a continuación." + } + }, + "fields": { + "projectId": { + "label": "ID del proyecto" + }, + "subscription": { + "label": "Nombre de la suscripción" + }, + "jsonKey": { + "label": "Clave JSON de cuenta de servicio" + } + }, + "intro": { + "title": "Cómo funciona", + "body": "UTMStack lee la actividad de auditoría directamente desde Google Cloud a través de Pub/Sub. Un sink de Logs Router transmite los registros de tu proyecto a un topic de Pub/Sub; UTMStack ejecuta un puller interno que lee una suscripción Pull de ese topic mediante una clave de cuenta de servicio. No se instala nada en tu proyecto de GCP.", + "diagram": { + "source": "Cloud Logging", + "edge1": "Logs Router", + "pubsub": "Pub/Sub", + "pubsubSub": "topic + suscripción", + "edge2": "extrae", + "utmstackSub": "alertas y correlación" + }, + "note": "Ningún agente se ejecuta en GCP — UTMStack extrae mensajes de la suscripción de Pub/Sub usando la clave JSON de cuenta de servicio que proporcionas a continuación." + }, + "credentials": { + "title": "Configuración de Pub/Sub", + "body": "Usa los valores obtenidos anteriormente para configurar UTMStack. Puedes monitorear más de un proyecto guardando configuraciones adicionales.", + "mapping": { + "intro": "Referencia de campos", + "projectId": "Project ID — el proyecto de GCP que contiene tu topic, suscripción y sink", + "subscription": "Nombre de suscripción — la suscripción Pull creada en el paso 2", + "jsonKey": "Clave JSON de cuenta de servicio — el archivo descargado en el paso 8" + } + } + }, + "azure": { + "sections": { + "sharedAccessPolicy": { + "title": "2 · Añade una directiva de acceso compartido", + "body": "Abre el Event Hub → Directivas de acceso compartido y crea una nueva directiva con el permiso Listen únicamente." + }, + "connectionString": { + "title": "3 · Copia la cadena de conexión principal", + "body": "Abre la directiva y copia la cadena de conexión principal. Tiene este aspecto: Endpoint=sb://...;SharedAccessKeyName=...;SharedAccessKey=..." + }, + "consumerGroup": { + "title": "4 · Crea un consumer group dedicado", + "body": "Abre el Event Hub → Consumer groups y crea uno nuevo para UTMStack. No reutilices $Default; dale a UTMStack su propio grupo para que los checkpoints no choquen con otros consumidores.", + "warn": "Crea un consumer group específicamente para UTMStack. No uses $Default ni ningún otro grupo que ya esté en uso — reutilizar un consumer group entre consumidores no relacionados puede provocar comportamientos inesperados y pérdida de eventos. Todas las instancias de UTMStack deben compartir el mismo consumer group para procesar los eventos en conjunto." + }, + "storageContainer": { + "title": "6 · Crea un contenedor dentro de la cuenta de almacenamiento", + "body": "Dentro de la cuenta de almacenamiento → Contenedores, crea uno nuevo. Anota el nombre del contenedor y la cadena de conexión de la cuenta (Claves de acceso → Cadena de conexión)." + }, + "eventGrid": { + "title": "7 · Registra el proveedor de recursos Event Grid", + "body": "En Suscripciones → Proveedores de recursos, registra Microsoft.EventGrid si aún no está. Esto permite que Azure reenvíe eventos de suscripción a tu Event Hub." + }, + "createEventHub": { + "title": "Crear un Event Hub", + "body": "En el Azure Portal, crea un namespace de Event Hubs y un Event Hub dentro de él. UTMStack leerá los eventos de este hub.", + "docLabel": "Inicio rápido: Crear un event hub usando el Azure portal" + }, + "createStorageAccount": { + "title": "Crear una Storage Account", + "body": "UTMStack necesita una Storage Account para registrar su posición de lectura. Crea una en la misma región que el Event Hub.", + "docLabel": "Inicio rápido: Crear una storage account" + }, + "storageConnection": { + "title": "Copiar la cadena de conexión de la Storage Account", + "body": "Obtén la cadena de conexión de la Storage Account con clave en: All services → Storage accounts → tu cuenta → Access keys. UTMStack la usa para almacenar los checkpoints del Event Hub." + }, + "createEventSubscription": { + "title": "Crear una Event Subscription", + "body": "En el panel Events de la suscripción, crea un nuevo evento haciendo clic en Events → Event Subscription." + }, + "configureEventSubscription": { + "title": "Apuntar la Event Subscription a tu Event Hub", + "body": "Configura la Event Subscription para enviar registros al Event Hub creado en el paso 1." + } + }, + "fields": { + "eventHubConnection": { + "label": "Cadena de conexión del Event Hub" + }, + "consumerGroup": { + "label": "Consumer group" + }, + "storageContainer": { + "label": "Nombre del contenedor de almacenamiento" + }, + "storageConnection": { + "label": "Cadena de conexión de la cuenta de almacenamiento" + } + }, + "intro": { + "title": "Cómo funciona", + "body": "UTMStack lee la actividad de auditoría directamente desde un Azure Event Hub. Configuras tu suscripción de Azure para transmitir eventos a un Event Hub; UTMStack ejecuta un puller interno que lee ese hub y registra su progreso en una Storage Account. No se instala nada en tu tenant de Azure.", + "diagram": { + "source": "eventos de suscripción", + "edge1": "transmite a", + "eventHub": "Event Hub", + "eventHubSub": "flujo de eventos", + "edge2": "extrae", + "utmstackSub": "alertas y correlación" + }, + "note": "Ningún agente se ejecuta en Azure — UTMStack extrae eventos del Event Hub usando las cadenas de conexión que proporcionas a continuación." + }, + "sampleLabel": "Cadena de conexión de ejemplo:", + "credentials": { + "title": "Configuración de Event Hub", + "body": "Usa los datos obtenidos en los pasos anteriores para configurar UTMStack. Puedes agregar más de un Event Hub guardando configuraciones adicionales.", + "mapping": { + "intro": "Referencia de campos", + "eventHubConnection": "Cadena de conexión de Event Hub — valor obtenido en el paso 3", + "consumerGroup": "Consumer group — valor obtenido en el paso 4", + "storageContainer": "Nombre del storage container — valor obtenido en el paso 6", + "storageConnection": "Cadena de conexión de storage account — valor obtenido en el paso 7" + } + } + }, + "aws": { + "intro": { + "title": "Cómo funciona", + "body": "UTMStack lee la actividad de auditoría directamente desde AWS CloudWatch Logs. CloudTrail captura llamadas a la API y eventos de gestión en tu cuenta de AWS, los reenvía a un log group de CloudWatch, y UTMStack consulta ese grupo para ingestar y correlacionar eventos.", + "diagram": { + "source": "eventos API", + "edge1": "CloudTrail", + "cloudwatchSub": "log groups", + "edge2": "consulta", + "utmstackSub": "alertas y correlación" + }, + "note": "No se instala nada en AWS — UTMStack extrae los eventos de log usando credenciales IAM de solo lectura que tú proporcionas." + }, + "iamSection": "Configurar usuario IAM", + "iam": { + "dashboard": { + "title": "Abrir el panel IAM", + "body": "Abre la consola de AWS, navega al panel IAM y selecciona Users." + }, + "addUser": { + "title": "Agregar un usuario", + "body": "Haz clic en Add user, introduce un nombre descriptivo y continúa al siguiente paso." + }, + "attachPolicy": { + "title": "Adjuntar la política de solo lectura", + "body": "En Permissions, adjunta la política requerida. Selecciona CloudWatchLogsReadOnlyAccess para acceso de solo lectura a CloudWatch." + }, + "createUser": { + "title": "Crear el usuario", + "body": "Revisa la configuración y haz clic en Create user para aprovisionar la cuenta." + }, + "openUser": { + "title": "Abrir el nuevo usuario", + "body": "Abre el usuario recién creado haciendo clic en su nombre para ver sus detalles y gestionar credenciales." + }, + "securityTab": { + "title": "Ir a Security credentials", + "body": "Selecciona la pestaña Security credentials para crear las claves de acceso programático." + }, + "createKey": { + "title": "Crear una clave de acceso", + "body": "Haz clic en Create access key y elige la opción para una aplicación que se ejecuta fuera de AWS (acceso programático)." + }, + "confirmKey": { + "title": "Confirmar la creación", + "body": "Confirma la creación de la clave de acceso. AWS generará un Access Key ID y un Secret Access Key." + }, + "downloadKey": { + "title": "Guardar las credenciales", + "body": "Descarga el archivo de credenciales o copia el Access Key ID y el Secret Access Key en un lugar seguro — el Secret Access Key solo se muestra una vez." + } + }, + "credentials": { + "title": "Introducir credenciales", + "body": "Pega el Access Key ID y el Secret Access Key obtenidos en los pasos anteriores. UTMStack verifica las credenciales contra AWS antes de guardarlas." + }, + "cloudwatchSection": "Configurar AWS CloudWatch", + "cloudwatch": { + "createGroup": { + "title": "Crear un CloudWatch Log Group", + "body": "Abre la consola de CloudWatch, elige Log management y haz clic en Create log group." + }, + "nameGroup": { + "title": "Nombrar el log group y configurar la retención", + "body": "Introduce el nombre utmstack para el log group y establece la retención en 1 día. Haz clic en Create log group." + }, + "openTrail": { + "title": "Abrir CloudTrail y crear un trail", + "body": "En la consola de CloudTrail, haz clic en Create trail para comenzar a configurar un nuevo trail." + }, + "configureTrail": { + "title": "Configurar entrega, validación e integración con CloudWatch", + "body": "En el formulario de creación del trail, establece las siguientes opciones:", + "items": [ + "Nombre y alcance del trail: introduce un nombre descriptivo; activa Apply trail to all accounts in my organization si necesitas recolección a nivel de organización.", + "Destino S3: elige Create new S3 bucket (o selecciona uno existente) para la entrega de logs sin procesar.", + "Cifrado: habilita Log file SSE-KMS y selecciona la clave KMS adecuada.", + "Validación de archivos de log: activa para garantizar la integridad de los logs entregados (recomendado).", + "CloudWatch Logs: habilita la entrega a CloudWatch, selecciona Use existing log group e introduce el nombre exacto utmstack.", + "Rol IAM: proporciona o crea el rol que CloudTrail usará para escribir en S3 y publicar en CloudWatch." + ] + }, + "eventTypes": { + "title": "Seleccionar tipos de eventos", + "body": "Habilita las categorías de eventos necesarias para la monitorización y auditoría.", + "management": { + "label": "1 · Eventos de gestión", + "body": "Habilita Management events y selecciona All para registrar toda la actividad de API que gestiona recursos de AWS (crear, actualizar, eliminar)." + }, + "data": { + "label": "2 · Eventos de datos", + "body": "Agrega un Data event. Elige S3 y selecciona Log all events para capturar operaciones a nivel de objeto como GetObject y PutObject." + }, + "network": { + "label": "3 · Eventos de actividad de red", + "body": "En la sección Network Activities agrega al menos un servicio (p. ej. ec2.amazonaws.com) y habilita Log all events." + } + }, + "review": { + "title": "Revisar y crear el trail", + "body": "En la pantalla Configure event aggregation acepta los valores predeterminados (o ajústalos si es necesario). Revisa todos los ajustes y haz clic en Create trail." + } + }, + "fields": { + "accessKeyId": { + "label": "ID de clave de acceso de AWS" + }, + "secretAccessKey": { + "label": "Clave de acceso secreta de AWS" + }, + "region": { + "label": "Región predeterminada de AWS" + }, + "logGroupName": { + "label": "Nombre del log group" + } + } + }, + "crowdstrike": { + "intro": { + "title": "Cómo funciona", + "body": "UTMStack lee detecciones y actividad de auditoría directamente desde la API de Event Streams de CrowdStrike Falcon. Creas un cliente API en Falcon con alcance de Event Streams; UTMStack ejecuta un puller interno que transmite eventos usando esas credenciales. No se instala nada en tus endpoints ni en Falcon.", + "diagram": { + "source": "detecciones y eventos", + "edge1": "Event Streams API", + "api": "Falcon API", + "apiSub": "flujo de eventos", + "edge2": "extrae", + "utmstackSub": "alertas y correlación" + }, + "note": "UTMStack no despliega ningún agente — extrae eventos de Falcon usando las credenciales de cliente API de solo lectura que proporcionas a continuación." + }, + "sections": { + "apiClients": { + "title": "Abrir API Clients and Keys", + "body": "En la consola de Falcon, abre el menú (ícono de hamburguesa, arriba a la izquierda) y ve a Support and resources → API Clients and Keys." + }, + "createClient": { + "title": "Crear un nuevo cliente API", + "body": "Haz clic en Create API Client para iniciar una nueva definición de cliente." + }, + "scopes": { + "title": "Nombrar el cliente y otorgar alcance de Event Streams", + "body": "Asigna al cliente un nombre descriptivo (UTMStack lo usa para identificar la fuente de eventos) y selecciona los alcances de API requeridos para Event Streams. Haz clic en Create para generar las credenciales." + }, + "recordCredentials": { + "title": "Registrar las credenciales", + "body": "Copia el Client ID, el Client Secret y la Base URL para tu región de CrowdStrike. El secreto se muestra solo una vez — guárdalo de forma segura. Pegarás los tres en el formulario a continuación." + } + }, + "credentials": { + "title": "Configuración de cliente API", + "body": "Usa las credenciales de los pasos anteriores para configurar UTMStack. Puedes agregar más de un cliente de CrowdStrike guardando configuraciones adicionales.", + "mapping": { + "intro": "Referencia de campos", + "appName": "Nombre de la app — el nombre descriptivo del cliente del paso 3 (identifica la fuente de eventos)", + "clientId": "Client ID — valor registrado en el paso 4", + "clientSecret": "Client Secret — valor registrado en el paso 4 (se muestra solo una vez)", + "cloudRegionUrl": "Base URL — el endpoint de tu región, p. ej. https://api.crowdstrike.com (us-1), https://api.us-2.crowdstrike.com (us-2), https://api.eu-1.crowdstrike.com (eu-1)" + } + }, + "fields": { + "appName": { + "label": "Nombre de la app" + }, + "clientId": { + "label": "Client ID" + }, + "clientSecret": { + "label": "Client Secret" + }, + "cloudRegionUrl": { + "label": "Base URL (región de nube)" + } + } + } + }, + "custom": { + "whenTitle": "Cuándo usar esto", + "whenBody": "Cuando tu fuente no está en el catálogo. Reenvía syslog o JSON arbitrario a UTMStack y define un analizador para normalizar campos.", + "endpointsTitle": "Puntos finales", + "syslogUdp": "Syslog (UDP)", + "syslogTls": "Syslog (TLS)", + "httpJson": "HTTP / JSON", + "payloadTitle": "Ejemplo de payload JSON", + "parserTitle": "Define el analizador", + "parserBody": "Los eventos entrantes se almacenan bajo el tipo de dato {{dataType}}. Añade un filtro de parseo para él de modo que el payload sin procesar se mapee a campos estructurados, y luego crea reglas de alerta encima.", + "openEditor": "Abrir editor de analizador", + "powershellLabel": "PowerShell (Ejecutar como administrador)", + "linuxLabel": "Linux — bash", + "macosLabel": "macOS — bash", + "exampleLabel": "Ejemplo de destino syslog en {{name}}:", + "intro": { + "title": "Cómo funciona", + "body": "Una integración personalizada ingiere registros de cualquier fuente que los módulos integrados no cubren. Instala el UTMStack Collector, registra un listener para tus datos con el protocolo de tu elección y apunta tu fuente hacia él.", + "note": "Elige a continuación el protocolo que puede enviar tu fuente (syslog UDP/TCP/TLS, o HTTP/HTTPS para JSON) — el Collector crea el tipo de datos automáticamente." + }, + "diagram": { + "source": "Tu fuente", + "sourceSub": "cualquier app o dispositivo", + "forwarder": "Collector", + "ingests": "ingiere", + "utmstackSub": "alertas y correlación" + }, + "choose": { + "title": "Elegir protocolo y puerto", + "body": "Selecciona cómo envía datos tu fuente y el puerto en el que debe escuchar el Collector, luego ejecuta el comando de activación en el host del Collector.", + "portLabel": "Puerto de escucha", + "tlsFirst": "Primero carga tu certificado y clave TLS en el Collector:", + "enableLabel": "Luego habilita la integración:", + "authNote": "Para requerir autenticación, agrega --auth bearer (token) o --auth hmac — el Collector imprime un token para usar en el encabezado Authorization." + }, + "send": { + "title": "Apuntar tu fuente al Collector", + "bodyNetwork": "Configura tu fuente para enviar syslog {{proto}} a {{host}}:{{port}}. La mayoría de los dispositivos tienen una opción de syslog remoto o reenvío de registros para esto.", + "bodyHttp": "Envía tus eventos como JSON mediante HTTP POST a {{endpoint}}. El cuerpo de cada solicitud es un evento JSON:", + "httpBindNote": "El listener HTTP/HTTPS se enlaza a 127.0.0.1 (el host del Collector) de forma predeterminada, así que envía desde una app que se ejecute en ese host — o usa un reverse proxy como intermediario. Para fuentes remotas, usa syslog (UDP/TCP/TLS)." + }, + "manualCommand": { + "title": "Optional — Enable via the command line instead", + "intro": "Prefer the terminal? SSH into the Collector host and run the command below — it matches whatever protocol and port you have selected above." + } + }, + "remoteEnable": { + "title": "Habilitar esta integración remotamente", + "body": "Elige un Collector, selecciona el protocolo y puerto, luego habilita la integración — sin necesidad de SSH.", + "noPermission": "No tienes permiso para gestionar integraciones remotas. Pide a un administrador que otorgue el permiso integrations.write.", + "loadingCollectors": "Cargando Collectors…", + "noCollectors": "Aún no hay Collector registrado. Instala uno arriba para habilitar integraciones remotamente.", + "forwarderOffline": "Este Collector está sin conexión y no puede recibir cambios de configuración en este momento.", + "legendOnline": "{{count}} en línea", + "legendOffline": "{{count}} sin conexión", + "legendTotal": "{{count}} total", + "forwarderLabel": "Collector", + "protoLabel": "Protocolo", + "portLabel": "Puerto", + "currentStateLoading": "Comprobando configuración actual…", + "currentlyEnabled": "Actual: habilitado · {{proto}} · puerto {{port}}", + "currentlyDisabled": "Actual: deshabilitado · {{proto}} · puerto {{port}}", + "authLabel": "Autenticación", + "authNone": "Ninguno", + "authBearer": "Token portador", + "authHmac": "Firma HMAC", + "pathLabel": "Ruta", + "signatureHeaderLabel": "Encabezado de firma", + "certTitle": "Certificado TLS", + "certLoading": "Comprobando estado del certificado…", + "certLoaded": "Un certificado válido ya está cargado en este Collector.", + "certMissing": "No hay certificado cargado aún — carga uno para habilitar este protocolo.", + "certInvalid": "El certificado cargado no es válido: {{error}}", + "certPemLabel": "Certificado", + "keyPemLabel": "Clave privada", + "caPemLabel": "Certificado CA", + "uploadCertsButton": "Cargar certificado", + "certUploadSuccess": "Certificado cargado.", + "certUploadError": "No se pudo cargar el certificado.", + "certReadError": "No se pudieron leer los archivos seleccionados.", + "enableButton": "Habilitar integración", + "disableButton": "Deshabilitar integración", + "enableSuccess": "Integración habilitada.", + "disableSuccess": "Integración deshabilitada.", + "enableError": "No se pudo actualizar la integración.", + "secretWarning": "Almacena este token de forma segura — no se mostrará nuevamente.", + "sendToInstance": "Enviar a la instancia", + "enterpriseFeature": "Esta es una función Enterprise.", + "addCollector": "Añadir Collector", + "addApiKey": "Añadir clave API", + "apiKeyLabel": "Clave API", + "apiKeyHint": "Primero necesitarás una clave API.", + "apiKeyPlaceholder": "Selecciona una clave API", + "apiKeyAddNew": "Añadir clave API…", + "apiKeyNone": "Todavía no hay claves API", + "forwarderNoRemoteControl": "Este forwarder se instaló con el control remoto deshabilitado. Ignora la configuración enviada desde aquí, y eso solo se cambia en la propia máquina." + } + }, + "codeBlock": { + "copy": "Copiar", + "copied": "Copiado" + }, + "createDrawer": { + "title": "Nueva integración personalizada", + "moduleName": "Nombre del módulo", + "moduleNameHint": "Identificador único. Sin espacios.", + "moduleNamePlaceholder": "mi-app-personalizada", + "prettyName": "Nombre para mostrar", + "prettyNamePlaceholder": "Mi App Personalizada", + "dataType": "Tipo de datos", + "dataTypePlaceholder": "Identificador único para este tipo de datos", + "icon": "Icono", + "iconHint": "PNG, SVG, JPEG, GIF o WEBP. Máximo 3MB. Se usa como logo de la integración.", + "iconPreview": "Vista previa del icono", + "dataTypeExists": "Este tipo de datos ya existe", + "invalidFileType": "El icono debe ser un archivo de imagen válido (PNG, JPEG, SVG, GIF, WEBP)", + "fileTooLarge": "El icono no debe exceder 3MB", + "fileReadError": "Error al leer el archivo", + "cancel": "Cancelar", + "create": "Crear integración", + "creating": "Creando…", + "editTitle": "Editar integración", + "save": "Guardar", + "saving": "Guardando…", + "currentIcon": "Ícono actual — sube un archivo para reemplazarlo", + "name": "Nombre de la integración", + "namePlaceholder": "p. ej. Acme Firewall", + "description": "Descripción", + "descriptionPlaceholder": "Qué ingiere esta integración y por qué (opcional)", + "identifierHint": "Se almacena como “{{id}}” (derivado del nombre)", + "nameTaken": "Ese nombre de integración no está disponible — ya existe una integración con ese identificador.", + "removeIcon": "Eliminar icono", + "defaultIconNote": "Icono predeterminado — sube un archivo para usar el tuyo." + }, + "toast": { + "created": "Integración creada", + "updated": "Integración actualizada", + "updateError": "Error al actualizar la integración" + }, + "delete": { + "title": "Eliminar integración", + "confirm": "¿Eliminar esta integración?", + "yes": "Eliminar", + "no": "Cancelar", + "deleted": "Integración eliminada", + "error": "No se pudo eliminar la integración" + }, + "modules": { + "WINDOWS_AGENT": "Recopila actividad del sistema Windows, seguridad y registros de eventos a través del agente ligero de UTMStack instalado en cada host.", + "LINUX_AGENT": "Recopila registros del sistema Linux, autenticación y auditoría a través del agente ligero de UTMStack instalado en cada host.", + "MACOS": "Recopila actividad de registros del sistema y seguridad de macOS desde endpoints Apple Mac a través del agente ligero de UTMStack.", + "VMWARE": "Ingesta el syslog del hipervisor VMware ESXi para monitorear la actividad y eventos del host de virtualización en UTMStack.", + "NETFLOW": "Ingesta registros NetFlow de routers y switches para monitorear patrones de tráfico de red y detectar anomalías.", + "AWS_IAM_USER": "Ingesta actividad de cuentas AWS y llamadas a API mediante CloudTrail y CloudWatch para auditar el uso, acceso y cambios en la nube.", + "AZURE": "Ingesta registros de plataforma y actividad de Microsoft Azure para monitorear cargas de trabajo en la nube, identidad y cambios en recursos.", + "O365": "Ingesta registros de auditoría de Microsoft 365 en Exchange, Teams, SharePoint y OneDrive para monitorear la actividad de usuarios y administradores.", + "O365_GRAPH": "Ingesta eventos de seguridad de Microsoft Graph: alertas, incidentes, auditoría del directorio, inicios de sesión, detecciones de riesgo y logs de auditoría de Purview para monitorear identidad y actividad de amenazas en tu tenant.", + "GCP": "Ingesta registros de auditoría y actividad de Google Cloud Platform para monitorear cómputo, almacenamiento e identidad en los proyectos.", + "KASPERSKY": "Ingesta detecciones de Kaspersky Security Center y telemetría de endpoints para correlacionar actividad de malware en la red.", + "ESET": "Ingesta detecciones y telemetría de endpoints de ESET PROTECT para correlacionar la defensa multicapa contra malware en tu infraestructura.", + "BITDEFENDER": "Ingesta detecciones de Bitdefender GravityZone y telemetría de endpoints para correlacionar amenazas en los dispositivos empresariales.", + "SENTINEL_ONE": "Ingesta detecciones de endpoints y telemetría de comportamiento de SentinelOne para correlacionar e investigar amenazas a escala.", + "SOPHOS": "Ingesta detecciones de Sophos Central en endpoints, servidores, firewall y correo electrónico para correlacionar amenazas en un solo lugar.", + "CROWDSTRIKE": "Ingesta detecciones de endpoints y cargas de trabajo de CrowdStrike Falcon para correlacionar actividad de amenazas nativas de la nube en UTMStack.", + "CISCO": "Ingesta registros de tráfico, VPN y amenazas del firewall Cisco ASA para monitorear la seguridad perimetral y el acceso en UTMStack.", + "MERAKI": "Ingesta el syslog del firewall y dispositivos de seguridad Cisco Meraki para monitorear el tráfico de red gestionado en la nube y las amenazas.", + "FIRE_POWER": "Ingesta registros de Cisco Firepower NGFW e IPS para monitorear intentos de intrusión y actividad de amenazas en el perímetro.", + "CISCO_SWITCH": "Ingesta el syslog y la telemetría de switches Cisco para monitorear el rendimiento de la red, cambios de configuración y seguridad.", + "FORTIGATE": "Ingesta registros de tráfico y amenazas de Fortinet FortiGate NGFW para monitorear la seguridad perimetral y la actividad de red.", + "FORTIWEB": "Ingesta registros WAF de Fortinet FortiWeb para monitorear ataques a aplicaciones web y proteger los servicios y APIs expuestos.", + "SOPHOS_XG": "Ingesta registros del firewall Sophos XG con filtrado web, IPS y VPN para monitorear el tráfico de red y las amenazas.", + "PALO_ALTO": "Ingesta registros de tráfico y amenazas de Palo Alto Networks NGFW para monitorear el uso de aplicaciones y la seguridad perimetral.", + "SONIC_WALL": "Ingesta registros de tráfico y amenazas de SonicWall NGFW para monitorear la seguridad perimetral y la actividad de red en UTMStack.", + "PFSENSE": "Ingesta registros del firewall y router pfSense con gestión unificada de amenazas para monitorear el tráfico de red y las amenazas.", + "MIKROTIK": "Ingesta registros de firewall, enrutamiento y redes inalámbricas de MikroTik RouterOS para monitorear la actividad y configuración de red.", + "AIX": "Recopila registros del sistema Unix IBM AIX, seguridad y auditoría para monitorear la actividad en plataformas IBM Power en UTMStack.", + "AS_400": "Recopila diarios del sistema y de auditoría de IBM AS/400 (IBM i) para monitorear la actividad de usuarios en plataformas OS/400 de rango medio.", + "ORACLE": "Ingesta registros de auditoría de Oracle Database para monitorear consultas, acceso y actividad privilegiada en tus bases de datos.", + "SURICATA": "Ingesta alertas de Suricata IDS/IPS y eventos de red para detectar intrusiones y tráfico malicioso en la red.", + "DECEPTIVE_BYTES": "Ingesta alertas de Deceptive Bytes desde su plataforma de engaño activo en endpoints para detectar actividad de atacantes de forma temprana.", + "GITHUB": "Ingesta registros de auditoría de GitHub para monitorear el acceso a repositorios, cambios de código y actividad organizacional para la seguridad del código fuente.", + "UTMSTACK": "Ingesta la telemetría propia de UTMStack de SIEM y XDR para monitorear el estado de la plataforma, la actividad interna y los eventos de autoauditoría.", + "NGINX": { + "name": "Nginx", + "description": "Ingesta los registros de acceso y error de Nginx para monitorear la actividad del servidor web, el tráfico del proxy inverso y las solicitudes de cliente." + }, + "APACHE": { + "name": "Apache", + "description": "Ingesta los registros de acceso y error de Apache HTTPD para monitorear la actividad del servidor web y las solicitudes de cliente." + }, + "APACHE2": { + "name": "Apache2", + "description": "Ingesta los registros del servidor web Apache2 (HTTPD) para monitorear el manejo de solicitudes, errores y el acceso en hosts Linux." + }, + "IIS": { + "name": "IIS", + "description": "Ingesta la actividad de acceso y archivos de registro de Internet Information Services (IIS) para monitorear el servicio web de Windows." + }, + "MYSQL": { + "name": "MySQL", + "description": "Ingesta la actividad de registros de MySQL para monitorear consultas, autenticación y acceso al almacén de datos." + }, + "POSTGRESQL": { + "name": "PostgreSQL", + "description": "Ingesta los registros de PostgreSQL para monitorear consultas, acceso y actividad en tus almacenes de datos." + }, + "MONGODB": { + "name": "MongoDB", + "description": "Ingesta la actividad de registros de MongoDB para monitorear el acceso a la base de datos documental, consultas y el comportamiento de la aplicación." + }, + "REDIS": { + "name": "Redis", + "description": "Ingesta la actividad de registros y telemetría de Redis para monitorear el uso del almacén de datos en memoria y las cargas de trabajo en tiempo real." + }, + "ELASTICsearch": { + "name": "ELASTICsearch", + "description": "Ingesta los registros de Elasticsearch para monitorear el motor de búsqueda y análisis y sus cargas de trabajo de aplicación." + }, + "LOGSTASH": { + "name": "Logstash", + "description": "Ingesta los registros de las tuberías de Logstash para monitorear la tubería de procesamiento de datos y sus transformaciones de eventos." + }, + "KIBANA": { + "name": "Kibana", + "description": "Ingesta los registros de Kibana para monitorear la capa de visualización y exploración de datos y su uso." + }, + "KAFKA": { + "name": "Apache Kafka", + "description": "Ingesta los registros de Apache Kafka para monitorear las tuberías de streaming en tiempo real, los brokers y el flujo de mensajes." + }, + "NATS": { + "name": "NATS", + "description": "Ingesta los registros de mensajería de NATS para monitorear el bus de mensajes, la conectividad y la entrega de eventos." + }, + "HAPROXY": { + "name": "HAProxy", + "description": "Ingesta los registros de HAProxy para monitorear el balanceo de carga, el tráfico del proxy y la disponibilidad de red." + }, + "TRAEFIK": { + "name": "Traefik", + "description": "Ingesta los registros de Traefik para monitorear el enrutamiento, el balanceo de carga y el tráfico del proxy entre cargas de trabajo." + }, + "OSQUERY": { + "name": "osquery", + "description": "Ingesta los registros de OsQuery para monitorear el estado del endpoint, las consultas y el inventario del sistema mediante solicitudes estilo SQL." + }, + "SYSLOG": { + "name": "Syslog", + "description": "Envía syslog (RFC 5424/3164) desde cualquier dispositivo o aplicación al extremo del collector para la ingesta centralizada de registros." + }, + "JSON": { + "name": "JSON Input", + "description": "Envía cargas de registros en JSON al extremo de ingesta para la captura estructurada de eventos de aplicaciones y scripts." + }, + "WINDOWS_SQL_SERVER": { + "name": "SQL Server Event Logs", + "description": "Collect Microsoft SQL Server audit and event records through the Windows Event Log and UTMStack agent." + }, + "WINDOWS_FILE_AUDITING": { + "name": "Windows File Access Auditing", + "description": "Collect Windows file access audit events through the Windows Event Log and UTMStack agent." + }, + "ELASTICSEARCH": { + "name": "Elasticsearch", + "description": "Ingesta los registros de Elasticsearch para monitorear el motor de búsqueda y análisis y sus cargas de trabajo de aplicación." + } + }, + "edit": { + "title": "Editar integración" + }, + "allCategories": "Todas las categorías", + "customOnly": "Personalizadas" + }, + "dataProcessing": { + "title": "Procesamiento de datos", + "subtitle": "Estadísticas de ingesta y procesamiento: eventos recibidos, descartados por etapa, y las principales fuentes y tipos.", + "ingestion": { + "title": "Ingesta", + "last24h": "últimas 24 horas", + "noData": "Sin datos en esta ventana.", + "loadError": "No se pudieron cargar las stats de ingesta.", + "groupBy": { + "dataSource": "Por fuente de datos", + "dataType": "Por tipo de dato" + }, + "status": { + "received": "Recibidos", + "parsing_dropped": "Descartados (parseo)", + "analysis_dropped": "Descartados (análisis)", + "correlation_dropped": "Descartados (correlación)", + "all": "Todos los eventos" + } + }, + "filters": { + "title": "Filtros", + "new": "Nuevo filtro", + "search": "Buscar por ruta…", + "refresh": "Actualizar", + "retry": "Reintentar", + "empty": "Ningún filtro coincide.", + "loadError": "No se pudieron cargar los filtros.", + "toggleError": "No se pudo cambiar el estado del filtro", + "system": "Sistema", + "custom": "Personalizado", + "systemReadonly": "Los filtros del sistema son de solo lectura", + "view": "Ver", + "edit": "Editar", + "ownership": { + "all": "Todos", + "system": "Sistema", + "custom": "Personalizados" + }, + "state": { + "all": "Todos", + "active": "Activos", + "inactive": "Inactivos" + }, + "col": { + "filter": "Filtro", + "type": "Tipo", + "active": "Activo", + "actions": "Acciones" + }, + "pageInfo": "{{from}}–{{to}} de {{count}}" + }, + "editor": { + "createTitle": "Nuevo filtro", + "editTitle": "Editar filtro", + "viewTitle": "Ver filtro", + "relPath": "Ruta", + "relPathHint": "Carpeta + archivo, p.ej. syslog/mi-filtro.yaml", + "content": "Pipeline (YAML)", + "contentHint": "Los pasos corren en orden: grok, rename, delete, plugins dynamic, …", + "save": "Guardar", + "saving": "Guardando…", + "saved": "Filtro guardado", + "saveError": "No se pudo guardar el filtro", + "cancel": "Cancelar", + "delete": "Eliminar", + "deleteConfirm": "¿Eliminar este filtro?", + "deleted": "Filtro eliminado", + "deleteError": "No se pudo eliminar el filtro" + }, + "kpi": { + "received": "Recibidos", + "dropped": "Descartados", + "dropRate": "{{rate}}% de descarte", + "stored": "Almacenados", + "throughput": "Rendimiento", + "perMin": "{{value}}/min", + "survival": "{{rate}}% conservados" + }, + "section": { + "overTime": "Eventos en el tiempo", + "top": "Top", + "dropReasons": "Razones de descarte" + }, + "live": { + "auto": "Auto" + }, + "pipeline": { + "title": "Pipeline de ingesta", + "stages": { + "received": "Recibidos", + "parsed": "Parseados", + "analyzed": "Analizados", + "stored": "Almacenados" + } + }, + "chart": { + "title": "Rendimiento en el tiempo", + "received": "Recibidos", + "dropped": "Descartados" + }, + "donut": { + "title": "Composición de descartes", + "dropped": "descartados" + }, + "breakdown": { + "title": "Top fuentes y tipos", + "bars": "Barras", + "treemap": "Treemap", + "showAll": "Ver los {{count}}", + "showLess": "Ver menos", + "lastSeen": "Visto por última vez", + "ago": "hace {{time}}" + } }, - "refresh": { - "title": "Actualización automática", - "options": { - "off": "Desactivado", - "10s": "10s", - "30s": "30s", - "1m": "1m", - "5m": "5m", - "15m": "15m" - } + "datasources": { + "limitBanner": { + "title": "Límite de datasources superado.", + "message": "Tienes {{count}} datasources pero tu licencia cubre {{limit}}. Los logs de los datasources que exceden el límite se están descartando.", + "cta": "Gestionar licencia", + "dismiss": "Descartar" + }, + "title": "Fuentes de datos", + "total": "{{count}} en total", + "subtitle": "Agentes, integraciones y fuentes directas que envían eventos. El estado se deriva de la última vez que se vio cada fuente.", + "connectSource": "Conectar una fuente", + "loading": "Cargando fuentes de datos…", + "loadFailed": "No se pudieron cargar las fuentes de datos.", + "retry": "Reintentar", + "none": "Ninguna fuente coincide con esta vista.", + "ingestion": { + "title": "Ingestión", + "received": "eventos recibidos", + "none": "Sin ingestión en las últimas 24 horas.", + "ago24h": "hace 24h", + "now": "ahora" + }, + "usage": { + "title": "Fuentes de datos", + "ofUnlimited": "de ilimitado", + "ofLimit": "de {{limit}}", + "overLimit": "Por encima del límite licenciado — los datos que excedan el tope están en riesgo.", + "configured": "configuradas" + }, + "tabs": { + "all": "Todas", + "agent": "Agentes", + "puller": "Integraciones", + "direct": "Directas", + "offline": "Sin conexión" + }, + "toolbar": { + "searchPlaceholder": "Buscar por nombre…", + "list": "Lista", + "cards": "Tarjetas", + "refresh": "Actualizar" + }, + "labels": { + "filteredBy": "Filtrado por label", + "add": "Agregar label…", + "addFirst": "Agregar un label…", + "hint": "Escribí un label y presioná Enter para agregarlo. Los cambios se guardan solos." + }, + "status": { + "live": "Activa", + "idle": "Inactiva", + "offline": "Sin conexión" + }, + "kind": { + "agent": "Agente", + "puller": "Integración", + "direct": "Directa" + }, + "cols": { + "source": "Fuente", + "type": "Tipo", + "status": "Estado", + "events24h": "Eventos 24h", + "lastSeen": "Vista por última vez" + }, + "time": { + "justNow": "ahora mismo", + "minutesAgo": "hace {{count}}m", + "hoursAgo": "hace {{count}}h", + "daysAgo": "hace {{count}}d" + }, + "drawer": { + "loading": "Cargando…", + "loadFailed": "No se pudo cargar la fuente de datos.", + "statsIdentity": "Stats e identidad", + "metadata": "Metadata", + "labelsSection": "Labels", + "dangerZone": "Zona de peligro", + "rows": { + "events24h": "Eventos 24h", + "lastSeen": "Vista por última vez", + "discovered": "Descubierta", + "kind": "Tipo de origen", + "dataType": "Tipo de dato", + "ip": "IP", + "id": "ID" + }, + "dangerText": "Eliminar quita esta fuente del registro. Los eventos históricos siguen disponibles en el Log Explorer; si la fuente sigue enviando datos, se redescubrirá.", + "delete": "Eliminar fuente", + "confirmDelete": "Confirmar eliminación", + "cancel": "Cancelar", + "viewLogs": "Ver logs", + "trend": "Tendencia de ingesta", + "noTrend": "No se recibieron eventos en esta ventana", + "logGap": "Último evento {{since}} — posible interrupción de logs" + }, + "toast": { + "labelsUpdated": "Labels actualizados", + "labelsFailed": "No se pudieron actualizar los labels", + "deleted": "Fuente eliminada", + "deleteFailed": "No se pudo eliminar" + }, + "console": { + "section": "Consola", + "sectionHint": "Ejecuta comandos en este host a través de su agente (respuesta en vivo).", + "open": "Abrir consola", + "close": "Cerrar", + "hint": "Escribe un comando y presiona Enter para ejecutarlo en el agente.", + "running": "Ejecutando…", + "placeholder": "Escribe un comando…", + "offline": "Este agente parece estar offline — puede que no responda a los comandos.", + "vars": { + "button": "Variables", + "title": "Variables de comandos", + "subtitle": "Úsalas en los comandos como", + "add": "Nueva variable", + "name": "Nombre", + "value": "Valor", + "description": "Descripción", + "isSecret": "Secreto (cifrado, enmascarado en la salida)", + "secret": "secreto", + "secretHint": "Déjalo en blanco para mantener el valor guardado.", + "save": "Guardar", + "cancel": "Cancelar", + "edit": "Editar", + "delete": "Eliminar", + "loading": "Cargando…", + "empty": "Aún no hay variables.", + "saved": "Variable guardada", + "deleted": "Variable eliminada", + "nameRequired": "El nombre es obligatorio", + "loadError": "No se pudieron cargar las variables", + "saveError": "No se pudo guardar la variable", + "deleteError": "No se pudo eliminar la variable", + "insert": "Insertar", + "valueRequired": "El valor es obligatorio" + }, + "disabled": "Agente offline — los comandos están deshabilitados", + "connError": "Error de conexión", + "cmdError": "Error de comando", + "shellSelect": "Tipo de shell", + "noRemoteControl": "Este agente se instaló con el control remoto deshabilitado. Rechaza los comandos, y eso solo se cambia en la propia máquina.", + "noRemoteControlShort": "Control remoto deshabilitado en este agente", + "password": { + "title": "Autenticación", + "hint": "Autentifíquese para ejecutar comandos en este agente.", + "tfaPrompt": "Código: ", + "confirm": "OK", + "cancel": "Cancelar", + "authError": "Error de autenticación", + "authHint": "Autentifíquese para ejecutar comandos en este agente.", + "authOk": "Autenticado." + } + }, + "sensitivity": { + "section": "Sensibilidad del activo", + "hint": "Criticidad de negocio (CIA, 0–3) de este activo. Las alertas que apuntan a su host/IP se ponderan con estos valores.", + "saved": "Sensibilidad actualizada", + "failed": "No se pudo actualizar la sensibilidad", + "save": "Guardar", + "confidentiality": "Confidencialidad", + "integrity": "Integridad", + "availability": "Disponibilidad", + "levels": { + "0": "Ninguna", + "1": "Baja", + "2": "Media", + "3": "Alta" + } + }, + "health": { + "online": "en línea", + "offline": "desconectados", + "total": "total" + } }, - "editor": { - "editing": "Edición", - "addWidget": "Agregar widget", - "save": "Guardar", - "discard": "Descartar", - "newTitle": "Nuevo widget", - "newSubtitle": "Elige un tipo de gráfico, selecciona una fuente de datos y dale forma visualmente. El SQL se genera automáticamente.", - "editTitle": "Editar widget", - "editSubtitle": "Ajusta la definición del gráfico. Los cambios se aplican en todos los lugares donde se usa este widget.", - "loading": "Cargando widget…", - "notFoundTitle": "Widget no encontrado", - "notFoundSubtitle": "Puede que haya sido eliminada o que no tengas acceso a ella.", - "backToDashboard": "Volver al panel", - "chartType": { - "title": "Tipo de gráfico" - }, - "chartTypes": { - "bar": { - "label": "Barras", - "description": "Compara valores entre categorías." - }, - "line": { - "label": "Línea", - "description": "Tendencias sobre un eje ordenado." - }, - "area": { - "label": "Área", - "description": "Línea rellena — resalta el volumen." - }, - "pie": { - "label": "Pastel", - "description": "Proporción del total por categoría." - }, - "metric": { - "label": "Métrica", - "description": "Un único valor escalar." + "adversaries": { + "title": "Vista de adversarios", + "subtitle": "Cada IP, host o usuario visto atacando tu entorno, con sus técnicas y objetivos.", + "countChip": "{{count}} adversarios", + "refresh": "Actualizar", + "search": "Buscar por IP, host, usuario, país, ASO…", + "empty": "Ningún adversario coincide.", + "loadError": "No se pudieron cargar los adversarios.", + "retry": "Reintentar", + "views": { + "all": "Todos", + "high": "Severidad alta", + "ip": "IPs", + "host": "Hosts", + "user": "Usuarios" }, - "table": { - "label": "Tabla", - "description": "Filas agregadas." + "threat": { + "critical": "Crítico", + "high": "Alto", + "medium": "Medio", + "low": "Bajo" }, - "list": { - "label": "Lista", - "description": "Filas sin procesar y sin agregación." + "kind": { + "ip": "IP", + "host": "Host", + "user": "Usuario" + }, + "layout": { + "list": "Lista", + "cards": "Tarjetas" + }, + "overview": { + "title": "Actividad de adversarios · últimas 24 horas", + "high": "severidad alta", + "countries": "países", + "alerts": "alertas", + "ago24": "hace 24h", + "ago12": "hace 12h", + "now": "ahora" + }, + "col": { + "adversary": "Adversario", + "threat": "Amenaza", + "alerts": "Alertas", + "targets": "Objetivos", + "lastSeen": "Última vez", + "victims": "Víctimas" }, - "region_map": { - "label": "Mapa de coordenadas", - "description": "Coloca marcadores en un mapamundi usando coordenadas de latitud y longitud." + "card": { + "alerts": "Alertas", + "techniques": "Técnicas", + "targets": "Objetivos" }, - "text": { - "label": "Texto", - "description": "Texto libre o salida simple por fila." + "tabs": { + "profile": "Perfil", + "techniques": "Técnicas", + "targets": "Objetivos", + "alerts": "Alertas" + }, + "drawer": { + "activity": "Actividad en 24 horas", + "identification": "Identificación", + "kindLabel": "Tipo", + "identifier": "Identificador", + "firstSeen": "Visto por primera vez", + "lastSeen": "Última vez", + "geolocation": "Geolocalización", + "country": "País", + "city": "Ciudad", + "topTechniques": "Técnicas principales", + "noTechniques": "Sin técnicas registradas.", + "targets": "Objetivos", + "noTargets": "Sin objetivos registrados.", + "recentAlerts": "Alertas recientes", + "noAlerts": "Sin alertas.", + "echoes": "{{count}} repeticiones" + }, + "relative": { + "justNow": "ahora mismo", + "minutesAgo": "hace {{count}}m", + "hoursAgo": "hace {{count}}h", + "daysAgo": "hace {{count}}d" + }, + "field": { + "ip": "IP", + "host": "Host", + "user": "Usuario", + "port": "Puerto", + "domain": "Dominio", + "mac": "MAC", + "country": "País", + "city": "Ciudad", + "asn": "ASN", + "aso": "ASO" } - }, - "dataSource": { - "title": "¿Qué datos?", - "dataset": "Conjunto de datos", - "noDatasetHint": "Elige un conjunto de datos para habilitar condiciones y agrupación." - }, - "widgetTitle": { - "label": "Título", - "placeholder": "Opcional — usa el tipo de gráfico por defecto" - }, - "dataset": { - "placeholder": "Selecciona un conjunto de datos…", - "loading": "Cargando conjuntos de datos…" - }, - "filters": { - "title": "Incluir solo eventos donde…", - "empty": "Sin condiciones: se incluyen todos los eventos del rango de tiempo.", - "add": "Agregar condición", - "remove": "Quitar", - "field": "Campo", - "fieldPlaceholder": "p. ej. host.name", - "operator": "Operador", - "value": "Valor", - "valuePlaceholder": "Valor", + }, + "timeRange": { + "quick": "Rangos rápidos", + "relative": "Relativo", + "absolute": "Absoluto", + "last": "Últimos", + "apply": "Aplicar", + "allTime": "Todo el tiempo", "from": "Desde", "to": "Hasta", - "noValue": "No se necesita valor", - "listPlaceholder": "Valores separados por coma" - }, - "operators": { - "IS": "es", - "IS_NOT": "no es", - "IS_ONE_OF_TERMS": "es uno de", - "IS_GREATER_THAN": "es mayor que", - "IS_LESS_THAN_OR_EQUALS": "es menor o igual que", - "IS_BETWEEN": "está entre", - "CONTAIN": "contiene", - "DOES_NOT_CONTAIN": "no contiene", - "START_WITH": "empieza con", - "ENDS_WITH": "termina con", - "EXIST": "existe", - "DOES_NOT_EXIST": "no existe" - }, - "dimension": { - "title": "Agrupar por", - "field": "Campo", - "placeholder": "Elige un campo para agrupar…" - }, - "table": { - "hint": "Muestra todos los campos de los registros. Agrega columnas para elegir algunos.", - "columnsTitle": "Columnas", - "allColumns": "Se mostrarán todas las columnas. Agrega campos para elegir columnas específicas.", - "addColumn": "Agregar una columna…", - "removeColumn": "Quitar columna" - }, - "chartPreview": { - "title": "Vista previa del gráfico", - "noQuery": "Elige un conjunto de datos para ver la vista previa.", - "error": "La consulta de vista previa falló." - }, - "chartTypeChip": { - "label": "Gráfico:" - }, - "chartTypeModal": { - "title": "Elige un tipo de gráfico", - "subtitle": "Elige cómo visualizar los datos. Puedes cambiarlo después.", - "confirm": "Continuar", - "swapTitle": "Cambiar tipo de gráfico", - "swapConfirm": "Aplicar" - }, - "saveVisualization": "Guardar widget", - "fieldSelect": { - "loading": "Cargando campos…", - "choose": "Elige un campo…" - }, - "toast": { - "notReady": "Elige un conjunto de datos, y un campo por el que desglosar, antes de guardar." - }, - "breakdown": { - "title": "Desglosar por", - "topValuesTable": "Tabla de valores principales", - "time": "En el tiempo", - "field": "Valores más frecuentes", - "interval": "Tamaño del intervalo", - "intervalAuto": "Automático", - "limit": "Cuántos", - "limitPlaceholder": "Predeterminado (50)", - "splitHint": "Opcional: una línea por cada valor de este campo." - }, - "editFilters": "Edit filters" - }, - "grid": { - "empty": "Este panel aún no tiene widgets.", - "missingVisualization": "Widget no disponible", - "unknownVisualization": "Widget" - }, - "widget": { - "renderError": "No se pudo renderizar este widget.", - "count": "Conteo", - "loading": "Cargando datos…", - "queryError": "No se pudieron cargar los datos del widget.", - "noData": "Sin datos para el rango de tiempo seleccionado.", - "regionMapEmpty": "No hay puntos con lat/lon válidos.", - "regionMapShapeHint": "El SQL debe devolver columnas de latitud y longitud (o un arreglo value [lat, lon, count]).", - "regionMapUnnamed": "(sin nombre)", - "regionMapValue": "valor: {{value}}", - "editAriaLabel": "Editar widget", - "removeAriaLabel": "Quitar widget", - "moveBack": "Mover atrás", - "moveForward": "Mover adelante", - "width": "Ancho", - "height": "Alto", - "widthSmall": "1 col", - "widthMedium": "2 cols", - "widthLarge": "3 cols", - "heightNormal": "Normal", - "heightTall": "Alto", - "incompleteSpec": "A este widget le falta parte de su pregunta." - }, - "form": { - "createTitle": "Nuevo panel", - "renameTitle": "Editar panel", - "name": "Nombre", - "namePlaceholder": "p. ej. Vista general de red", - "description": "Descripción", - "descriptionPlaceholder": "Opcional", - "cancel": "Cancelar", - "create": "Crear", - "save": "Guardar" - }, - "confirm": { - "deleteTitle": "Eliminar panel", - "delete": "¿Eliminar el panel «{{name}}»? Esta acción no se puede deshacer.", - "deleteWidgetsTitle": "Eliminar widgets", - "deleteWidgets_one": "¿Eliminar este widget? Esta acción no se puede deshacer.", - "deleteWidgets_other": "¿Eliminar {{count}} widgets? Esta acción no se puede deshacer.", - "dismissTitle": "Quitar panel", - "dismiss": "¿Quitar el panel predeterminado «{{name}}»? Después podrás crear uno nuevo a partir de él con \"Nuevo\" → \"Desde una existente\"." - }, - "page": { - "noSelection": "Elige un panel de la lista o crea uno para comenzar.", - "loading": "Cargando widgets…" - }, - "toast": { - "created": "Panel creado.", - "createFailed": "No se pudo crear el panel.", - "updated": "Panel actualizado.", - "updateFailed": "No se pudo actualizar el panel.", - "deleted": "Panel eliminado.", - "deleteFailed": "No se pudo eliminar el panel.", - "layoutSaved": "Distribución guardada.", - "layoutSaveFailed": "No se pudo guardar la distribución.", - "visualizationCreated": "Widget creado.", - "visualizationCreateFailed": "No se pudo crear el widget.", - "visualizationUpdated": "Widget actualizado.", - "visualizationUpdateFailed": "No se pudo actualizar el widget.", - "visualizationDeleted": "Widget eliminado.", - "visualizationDeleteFailed": "No se pudo eliminar el widget.", - "filterCreated": "Filtro creado.", - "filterUpdated": "Filtro actualizado.", - "filterDeleted": "Filtro eliminado.", - "filterCreateFailed": "No se pudo crear el filtro.", - "filterUpdateFailed": "No se pudo actualizar el filtro.", - "filterDeleteFailed": "No se pudo eliminar el filtro.", - "filtersSaved": "Filters saved.", - "filtersSaveFailed": "Could not save filters." + "now": "ahora", + "units": { + "minutes": "minutos", + "hours": "horas", + "days": "días", + "weeks": "semanas", + "months": "meses" + }, + "presets": { + "15m": "Últimos 15 minutos", + "1h": "Última hora", + "6h": "Últimas 6 horas", + "24h": "Últimas 24 horas", + "7d": "Últimos 7 días", + "30d": "Últimos 30 días" + } }, - "newDashboard": { - "title": "Nuevo panel", - "subtitle": "Crea un panel en blanco. Podrás agregar widgets después de guardarlo.", - "modeManual": "Crear manualmente", - "modeAi": "Con IA", - "aiLocked": "Activa SOC-AI y configúralo para poder usar esto.", - "aiDescriptionLabel": "¿Qué querés que muestre este panel?", - "aiDescriptionPlaceholder": "ej. Logins fallidos por país, últimos 7 días", - "aiCreate": "Crear con IA", - "aiOpenerWithDetails": "Creá un panel llamado \"{{name}}\" que muestre: {{description}}" + "socAi": { + "title": "Configuración de SOC-AI", + "subtitle": "Configura el agente de IA que triagea alertas y potencia el asistente de operaciones.", + "section": { + "connection": "Modelo y conexión", + "auth": "Autenticación", + "behavior": "Comportamiento del triage", + "advanced": "Avanzado" + }, + "usage": { + "title": "Uso", + "chat": "Chat completions (hoy)", + "unavailable": "El uso todavía no está disponible.", + "resetsIn": "Se reinicia en {{time}}" + }, + "provider": { + "label": "Proveedor", + "hint": "Define el formato. Cualquiera distinto de Anthropic usa la API compatible con OpenAI." + }, + "model": { + "label": "Modelo", + "hint": "Identificador del modelo del proveedor.", + "customOption": "Modelo personalizado…", + "customPlaceholder": "Ingresa un ID de modelo" + }, + "url": { + "label": "URL de la API", + "hint": "Déjalo vacío para usar el endpoint por defecto del proveedor." + }, + "apiKey": { + "label": "API key", + "hint": "Credencial enviada al proveedor.", + "setHint": "Hay una key guardada. Déjalo en blanco para mantenerla." + }, + "authType": { + "label": "Tipo de autenticación", + "hint": "Cómo se envían las credenciales a tu gateway.", + "options": { + "apiKey": "API Key", + "bearer": "Bearer", + "customHeaders": "Cabeceras personalizadas", + "none": "Ninguna" + } + }, + "authHeaderName": { + "label": "Nombre de cabecera de auth", + "hint": "Cabecera que lleva la key (p.ej. api-key para Azure)." + }, + "authToken": { + "label": "Token Bearer", + "hint": "Credencial enviada al proveedor.", + "setHint": "Hay un token guardado. Déjalo en blanco para mantenerlo." + }, + "customHeaders": { + "label": "Cabeceras personalizadas", + "hint": "Cabeceras extra en cada request. Los valores se cifran; \"*****\" mantiene el guardado.", + "keyPlaceholder": "Nombre de la cabecera", + "valuePlaceholder": "Valor", + "addRow": "Agregar cabecera", + "remove": "Quitar cabecera" + }, + "maxTokens": { + "label": "Máx. tokens", + "hint": "Tokens máximos por respuesta del LLM." + }, + "maxToolIterations": { + "label": "Máx. iteraciones de tools", + "hint": "Tope del bucle planear → tool → observar del agente." + }, + "autoAnalyze": { + "label": "Analizar alertas automáticamente", + "hint": "Triagea las alertas entrantes en tiempo real." + }, + "allowIncidents": { + "label": "Permitir gestionar incidentes", + "hint": "El agente de triage puede crear o actualizar incidentes cuando decide que una alerta lo amerita." + }, + "changeAlertStatus": { + "label": "Cambiar estado de alerta", + "hint": "Permite al agente fijar el estado de una alerta en el triage." + }, + "automaticIncidentCreation": { + "label": "Crear incidentes", + "hint": "Permite al agente abrir incidentes desde alertas triageadas." + }, + "allowedWriteTools": { + "label": "Tools de escritura permitidas", + "hint": "Un nombre de tool MCP por línea que el agente puede usar (p.ej. alerts.update_status). Las notas siempre están permitidas." + }, + "save": "Guardar configuración", + "saving": "Verificando y guardando…", + "saved": "Configuración de SOC-AI guardada", + "saveError": "No se pudo guardar la configuración", + "loadError": "No se pudo cargar la configuración", + "modelRequired": "El modelo es obligatorio", + "applyTags": { + "label": "Aplicar tags", + "hint": "Permite al agente etiquetar alertas durante el triage." + }, + "note": { + "azure": "Pega el endpoint completo de tu deployment de Azure como URL; el modelo es el nombre del deployment. La auth usa la cabecera api-key.", + "ollama": "Apunta la URL a tu host de Ollama. No hace falta API key para una instancia local.", + "custom": "Cualquier endpoint compatible con OpenAI. Define la URL, la auth y las cabeceras extra que necesite tu gateway.", + "threatwinds": "Usa tu licencia de UTMStack automáticamente — no necesita API key. Se factura a través de tu suscripción de ThreatWinds." + }, + "chat": { + "title": "Asistente SOC", + "dashboardCreateTitle": "Creador de paneles", + "empty": "Pregunta lo que quieras sobre tus alertas, detecciones o la consola — puedo investigar y actuar sobre el SIEM.", + "tryPrefix": "Prueba", + "suggestion": "¿cuántas alertas abiertas hay, agrupadas por adversario?", + "placeholder": "Escribe una pregunta…", + "ask": "Preguntar", + "send": "Enviar", + "collapse": "Contraer", + "expand": "Expandir", + "clear": "Limpiar conversación", + "close": "Cerrar", + "copy": "Copiar", + "copied": "Copiado", + "errorGeneric": "Algo salió mal.", + "errorUnreachable": "No se pudo contactar al asistente.", + "compacting": "Compactando contexto…", + "dashboardEditTitle": "Editor de paneles", + "editingDashboard": "Editando: {{name}}", + "soarEditTitle": "Editor de flujos SOAR", + "soarCreateTitle": "Crear flujo SOAR", + "editingFlow": "Editando flujo: {{name}}" + }, + "focus": { + "alert": "Alerta", + "incident": "Incidente", + "remove": "Dejar de compartir con el asistente" + }, + "inheritance": { + "inherited": "Siguiendo la configuración por defecto de la instancia. Si guardas aquí, este tenant pasa a tener la suya.", + "own": "Este tenant tiene su propia configuración.", + "revert": "Volver a la de la instancia", + "reverting": "Volviendo…", + "reverted": "Ahora sigue la configuración de la instancia" + }, + "allowance": { + "title": "Consumo de IA hoy", + "ofLimit": "de {{limit}} peticiones", + "denied": "peticiones — la IA no está disponible para este tenant", + "hint": "Lo fija quien opera la instancia. Se reinicia a medianoche UTC." + } }, - "newVisualization": { - "title": "Nuevo widget", - "subtitle": "Define un gráfico reutilizable a partir de una consulta SQL y una configuración de ECharts.", - "sqlQuery": "Consulta SQL", - "sqlQueryPlaceholder": "SELECT bucket, count(*) FROM logs GROUP BY bucket", - "sqlQueryHint": "Usa los marcadores timeFilter, from y to (entre dobles llaves) para aplicar el selector de tiempo al renderizar.", - "config": "Configuración del gráfico (opción de ECharts, JSON)", - "configHint": "Debe ser JSON válido. Las filas del SQL se exponen como `dataset.source` — conecta tus series con `encode`.", - "configError": "JSON no válido: {{error}}" - }, - "visualizationList": { - "title": "Widgets", - "subtitle": "{{count}} widget(s) disponible(s).", - "subtitleFiltered": "Mostrando {{shown}} de {{total}}.", - "create": "Nueva", - "searchPlaceholder": "Buscar widgets…", - "loading": "Cargando widgets…", - "empty": "Aún no hay widgets.", - "emptyFiltered": "Ningún widget coincide con los filtros actuales.", - "delete": "Eliminar", - "deleteTitle": "Eliminar widget", - "confirmDelete": "¿Eliminar el widget «{{name}}»? Esta acción no se puede deshacer.", - "filters": { - "search": "Buscar", - "chartType": "Tipo de gráfico", - "allChartTypes": "Todos los tipos de gráfico", - "source": "Fuente", - "allSources": "Todas las fuentes", - "createdAt": "Creada", - "modifiedAt": "Modificada", - "createdRangeTitle": "Rango personalizado — Creada", - "modifiedRangeTitle": "Rango personalizado — Modificada", - "pickRange": "Elegir un rango", - "datePresets": { - "all": "Todo el tiempo", - "today": "Hoy", - "last7": "Últimos 7 días", - "last30": "Últimos 30 días", - "lastYear": "Último año", - "custom": "Rango personalizado" - }, - "clear": "Limpiar filtros" - }, - "col": { - "name": "Nombre", - "chartType": "Tipo de gráfico", - "source": "Fuente", - "description": "Descripción", - "created": "Creada", - "modified": "Modificada" - } - }, - "tabs": { - "dashboards": "Tableros", - "visualizations": "Widgets", - "newDashboard": "Nuevo tablero", - "unsetDefault": "Quitar predeterminado", - "options": "Opciones" - }, - "picker": { - "none": "Seleccionar tablero", - "search": "Buscar tableros…", - "new": "Nuevo tablero", - "setDefault": "Marcar como predeterminado", - "empty": "Sin tableros" - }, - "empty": { - "title": "Aún no hay tableros", - "body": "Crea tu primer tablero para ver tus datos de seguridad de un vistazo.", - "cta": "Crear tablero" - }, - "filters": { - "addTitle": "Añadir filtro", - "editTitle": "Editar filtro", - "removeTitle": "Eliminar filtro", - "removeConfirm": "¿Eliminar el filtro \"{{label}}\"? Esta acción no se puede deshacer.", - "remove": "Eliminar", - "editAria": "Editar filtro", - "removeAria": "Eliminar filtro", - "saving": "Guardando…", - "addChip": "Añadir filtro", - "chooseValue": "Choose…", - "selected": "selected", - "loading": "Loading values…", - "searchPlaceholder": "Search values…", - "noValues": "No values available.", - "loadError": "Could not load values.", - "clear": "Clear", - "editorTitle": "Dashboard filters", - "editorHint": "Add dropdown chips that filter every widget on this dashboard.", - "emptyEditor": "No filter chips yet. Add one to get started.", - "cancel": "Cancel", - "save": "Save", - "field": { - "dataset": "Data set", - "field": "Field", - "chooseField": "Choose a field…", - "label": "Label", - "labelPlaceholder": "e.g. Host", - "placeholder": "Placeholder", - "placeholderPlaceholder": "e.g. Pick a host", - "multiple": "Multiple", - "searchable": "Searchable" - } - }, - "duplicate": { - "copyName": "{{name}} (copia)" - } - }, - "settings": { - "title": "Configuración", - "license": "Licencia", - "notifications": "Notificaciones", - "connectionKey": "Clave de conexión", - "dataRetention": "Retención de datos", - "indices": "Índices", - "theme": "Tema", - "branding": "Marca", - "apiKeys": "Claves API", - "identityProviders": "Proveedores de identidad", - "email": "Configuración de correo", - "dateFormat": "Formato de fecha", - "language": "Idioma", - "auditLogs": "Registros de auditoría", - "about": "Acerca de", - "socAi": "SOC-AI", - "supportAccess": "Acceso de soporte", - "threatwinds": "Integración de ThreatWinds" - }, - "topbar": { - "theme": { - "light": "Modo claro", - "dark": "Modo oscuro" - }, - "manageLicense": "Gestionar licencia", - "profile": { - "profile": "Perfil", - "license": "Licencia", - "logout": "Cerrar sesión" - } - }, - "notifications": { - "title": "Notificaciones", - "markAllRead": "Marcar todas como leídas", - "empty": "No tienes notificaciones.", - "viewAll": "Ver todas", - "markRead": "Marcar como leída", - "markUnread": "Marcar como no leída", - "delete": "Eliminar", - "subtitle": "{{total}} en total · {{unread}} sin leer", - "allCaughtUp": "Todo al día.", - "loadFailed": "No se pudieron cargar las notificaciones." - }, - "pagination": { - "perPage": "Por página", - "pageOf": "Página {{page}} de {{total}}", - "previous": "Anterior", - "next": "Siguiente" - }, - "license": { - "title": "Licencia", - "subtitle": "Tu edición, capacidades y archivo de licencia.", - "loading": "Cargando licencia…", - "loadError": "No se pudo cargar la información de la licencia.", - "statusLabel": "Estado", - "status": { - "community": "Community", - "active": "Activa", - "expiring": "Por expirar", - "expired": "Expirada" - }, - "edition": "Edición", - "enterprise": "Enterprise", - "community": "Community", - "editionLine": "Edición {{edition}}", - "datasourceLimit": "Límite de datasources", - "unlimited": "Ilimitado", - "mssp": "MSSP / multi-tenant", - "enabled": "Activado", - "licenseType": "Tipo de licencia", - "instanceId": "ID de instancia", - "enterpriseUnlocked": "Funciones Enterprise desbloqueadas", - "validUntil": "Válida hasta", - "noExpiry": "Sin expiración", - "timeRemaining": "Tiempo restante", - "expiredAgo": "Expiró hace {{days}}d", - "daysShort": "{{days}}d", - "msspShort": "MSSP", - "communityEdition": "Edición Community", - "communityBlurb": "Gratuita y de código abierto. Sube una licencia Enterprise abajo para desbloquear multi-tenancy, SSO, mayores límites de datasources y cumplimiento avanzado.", - "upgrade": "Actualizar a Enterprise", - "uploadTitle": "Subir una licencia", - "uploadBlurb": "Instala o reemplaza el archivo LICENSE firmado. El servidor valida la firma y la expiración antes de aplicarlo. Solo admin.", - "installLicense": "Instalar licencia", - "chooseFile": "Seleccionar archivo", - "noFileSelected": "Ningún archivo seleccionado", - "toast": { - "installed": "Licencia instalada — edición {{edition}}.", - "adminRequired": "Se requieren privilegios de administrador para subir una licencia.", - "invalid": "Archivo de licencia inválido o expirado.", - "installFailed": "No se pudo instalar la licencia." - }, - "ingestLimit": "Volumen de ingesta", - "notMetered": "Sin medición", - "gbPerMonth": "{{gb}} GB/mes" - }, - "audit": { - "title": "Registro de auditoría", - "subtitle": "Registro de cada acción relevante para la seguridad.", - "totalEntries": "{{total}} entradas en total.", - "loadError": "No se pudo cargar el registro de auditoría", - "stats": { - "totalEntries": "Entradas totales", - "acrossAllTime": "De todo el tiempo", - "successRate": "Tasa de éxito", - "failuresOnPage_one": "{{count}} fallo en esta página", - "failuresOnPage_other": "{{count}} fallos en esta página", - "topAction": "Acción principal", - "onPage": "{{count}} en esta página", - "uniqueActors": "Actores únicos", - "includingSystem": "Incluyendo el sistema" - }, - "filters": { - "title": "Filtros", - "clear": "Limpiar", - "last24h": "Últimas 24h", - "failuresOnly": "Solo fallos", - "authEvents": "Eventos de autenticación", - "actionPrefix": "Prefijo de acción", - "actionPlaceholder": "p.ej. auth., user.update", - "status": "Estado", - "any": "Cualquiera", - "resourceType": "Tipo de recurso", - "resourceTypePlaceholder": "user, alert…", - "resourceId": "ID de recurso", - "user": "Usuario", - "userPlaceholder": "login…" - }, - "statusValue": { - "success": "Éxito", - "failure": "Fallo" - }, - "table": { - "timestamp": "Fecha y hora", - "actor": "Actor", - "action": "Acción", - "resource": "Recurso", - "status": "Estado", - "ip": "IP", - "loading": "Cargando…", - "emptyTitle": "Ninguna entrada coincide con estos filtros.", - "emptyHint": "Prueba a limpiar los filtros o ampliar el rango de fechas.", - "system": "sistema", - "view": "Ver" - }, - "drawer": { - "entry": "entrada #{{id}}", - "overview": "Resumen", - "raw": "JSON crudo", - "error": "Error", - "actor": "Actor", - "resource": "Recurso", - "ip": "IP", - "userAgent": "Agente de usuario", - "session": "Sesión", - "metadata": "Metadatos", - "copy": "Copiar", - "copied": "Copiado", - "copyJson": "Copiar JSON" - } - }, - "team": { - "title": "Equipo", - "subtitle": "Gestiona los usuarios y sus roles.", - "tabs": { - "members": "Miembros", - "roles": "Roles y permisos" - }, - "toast": { - "rolesLoadFailed": "No se pudieron cargar los roles", - "userLoadFailed": "No se pudo cargar el usuario", - "rolesUpdated": "Roles actualizados", - "userReactivated": "Usuario reactivado", - "userDeactivated": "Usuario desactivado", - "tfaReset": "Autenticación en dos pasos restablecida", - "invitationSent": "Invitación enviada", - "loginOrEmailInUse": "Ese usuario o correo ya está en uso", - "invalidRequest": "Solicitud inválida", - "noPermission": "No tienes permiso para hacer eso", - "userNotFound": "Usuario no encontrado", - "operationFailed": "La operación falló", - "emailInUse": "Ese correo ya está en uso", - "roleCreated": "Rol creado", - "roleUpdated": "Rol actualizado", - "roleDeleted": "Rol eliminado", - "roleNameInUse": "Ya existe un rol con ese identificador", - "roleImmutable": "Los roles del sistema no se pueden modificar", - "permissionsLoadFailed": "No se pudieron cargar los permisos", - "localUserCreated": "Usuario local creado" - }, - "members": { - "searchPlaceholder": "Buscar por nombre o correo…", - "invite": "Invitar usuario", - "colUser": "Usuario", - "colRoles": "Roles", - "col2fa": "2FA", - "colStatus": "Estado", - "loading": "Cargando usuarios…", - "loadFailed": "No se pudieron cargar los usuarios.", - "retry": "Reintentar", - "noSearchMatch": "Ningún usuario coincide con tu búsqueda.", - "none": "Aún no hay usuarios.", - "noRole": "ninguno", - "on": "Sí", - "off": "No", - "countLabel_one": "{{count}} usuario · página {{page}} de {{pages}}", - "countLabel_other": "{{count}} usuarios · página {{page}} de {{pages}}", - "federated": "SSO" - }, - "status": { - "inactive": "Inactivo", - "pendingPassword": "Contraseña pendiente", - "active": "Activo", - "pending": "Invitación pendiente", - "suspended": "Suspendido" - }, - "drawer": { - "createdBy": "creado por {{actor}}", - "loading": "Cargando…", - "profileTitle": "Perfil", - "profileSubtitle": "Solo el usuario puede editar esto, desde su propio perfil.", - "name": "Nombre", - "username": "Usuario", - "email": "Correo", - "language": "Idioma", - "accountTitle": "Cuenta", - "status": "Estado", - "statusActive": "Activo", - "statusInactive": "Inactivo", - "tfa": "2FA", - "tfaEnabled": "Activada", - "tfaNotConfigured": "No configurado", - "resetTfa": "Restablecer", - "resetTfaHint": "Desactiva el 2FA de este usuario para que lo reconfigure en su próximo inicio de sesión", - "resetTfaConfirmTitle": "¿Restablecer la autenticación en dos pasos?", - "resetTfaConfirmBody": "Esto desactiva el 2FA de {{name}}. Iniciará sesión solo con su contraseña y podrá configurarlo de nuevo desde su perfil.", - "resetTfaConfirm": "Restablecer 2FA", - "pendingPasswordNote": "Aún usa la contraseña temporal (invitación no completada).", - "lastModified": "Modificado {{time}}", - "rolesTitle": "Roles", - "rolesSubtitle": "Los roles otorgan permisos de módulo. Un usuario puede tener más de uno.", - "noRoleWarning": "Sin rol asignado — el usuario no tendrá acceso a ningún módulo.", - "deactivate": "Desactivar", - "reactivate": "Reactivar", - "waitingInvite": "Esperando a que el usuario acepte la invitación.", - "cancel": "Cancelar", - "saving": "Guardando…", - "saveRoles": "Guardar roles", - "created": "creado {{time}}", - "pendingNote": "La invitación aún no se ha aceptado.", - "federatedNote": "Inicia sesión mediante un proveedor de identidad." - }, - "invite": { - "title": "Invitar usuario", - "description": "La cuenta se crea inactiva. El usuario recibe un correo para establecer su contraseña y activarla.", - "username": "Usuario", - "usernameHint": "Al menos 3 caracteres.", - "email": "Correo", - "firstName": "Nombre", - "lastName": "Apellido", - "roles": "Roles", - "cancel": "Cancelar", - "sending": "Enviando…", - "send": "Enviar invitación", - "name": "Nombre", - "emailHint": "Es la dirección con la que iniciará sesión.", - "localDescription": "La cuenta se crea con una contraseña y se activa de inmediato. No se envía ningún correo.", - "modeInvite": "Invitar usuario", - "modeLocal": "Crear usuario local", - "passwordLabel": "Contraseña", - "passwordPlaceholder": "Establezca una contraseña segura", - "localUserNote": "Este usuario no recibirá un correo y será activado automáticamente.", - "createLocal": "Crear usuario", - "passwordRules": { - "length": "Al menos 8 caracteres", - "case": "Al menos una mayúscula y una minúscula", - "special": "Al menos un carácter especial" - }, - "emailInvalid": "Introduzca una dirección de correo válida" - }, - "rolePicker": { - "none": "No hay roles disponibles." - }, - "roles": { - "loading": "Cargando roles…", - "loadFailed": "No se pudieron cargar los permisos de los roles.", - "readonlyNote": "Los roles y sus permisos los define el sistema y son de solo lectura. Asígnalos a los usuarios desde la pestaña Miembros.", - "permissionsCount_one": "{{count}} permiso", - "permissionsCount_other": "{{count}} permisos", - "modulesCount_one": "{{count}} módulo", - "modulesCount_other": "{{count}} módulos", - "matrixTitle": "Matriz de permisos", - "matrixSubtitle": "Lo que cada rol puede hacer, por módulo.", - "permission": "Permiso", - "systemNote": "Los roles del sistema vienen con la plataforma y no se pueden editar. Los que crees pertenecen a este tenant.", - "newRole": "Nuevo rol", - "edit": "Editar", - "delete": "Eliminar", - "systemBadge": "Sistema", - "createTitle": "Nuevo rol", - "editTitle": "Editar rol", - "editorSubtitle": "Elige qué puede hacer este rol. Un usuario puede tener más de uno.", - "nameLabel": "Identificador", - "nameHint": "Se usa en el código y en la API. Por ejemplo, ROLE_AUDITOR.", - "displayNameLabel": "Nombre visible", - "descriptionLabel": "Descripción", - "permissionsLabel": "Permisos", - "selectedCount": "{{count}} seleccionados", - "toggleAll": "todos", - "loadingPermissions": "Cargando permisos…", - "save": "Guardar rol", - "deleteConfirmTitle": "¿Eliminar este rol?", - "deleteConfirmBody": "Se eliminará {{name}}. Los usuarios que solo tengan este rol se quedarán sin acceso a los módulos." - }, - "langDefault": "Predeterminado del sistema", - "relative": { - "justNow": "ahora mismo", - "minutesAgo": "hace {{count}} min", - "hoursAgo": "hace {{count}} h", - "daysAgo": "hace {{count}} d" - }, - "roleNames": { - "ROLE_ADMIN": "Administrador", - "ROLE_USER": "Usuario" - }, - "roleDescriptions": { - "ROLE_ADMIN": "Acceso total a todos los recursos", - "ROLE_USER": "Usuario estándar con acceso de lectura a nivel de módulo" - }, - "actions": { - "read": "Lectura", - "write": "Escritura", - "delete": "Eliminación" - }, - "resources": { - "adaudit": "Auditoría AD", - "alerts": "Alertas", - "audit": "Registro de auditoría", - "compliance": "Cumplimiento", - "config": "Configuración", - "dashboards": "Paneles", - "datasources": "Datasources", - "eventprocessing": "Procesamiento de eventos", - "idp": "Proveedores de identidad", - "incidents": "Incidentes", - "integrations": "Integraciones", - "loganalyzer": "Analizador de logs", - "opensearch": "OpenSearch", - "roles": "Roles", - "soar": "SOAR", - "users": "Usuarios", - "notifications": "Notificaciones", - "socai": "SOC AI", - "tenant": "Tenants", - "threatintel": "Inteligencia de amenazas" - } - }, - "apiKeys": { - "title": "Claves API", - "subtitle": "Tokens de acceso programático para la API de UTMStack.", - "new": "Nueva clave API", - "searchPlaceholder": "Buscar por nombre o IP permitida…", - "refresh": "Actualizar", - "loading": "Cargando claves API…", - "loadFailed": "No se pudieron cargar las claves API.", - "retry": "Reintentar", - "noSearchMatch": "Ninguna clave API coincide con tu búsqueda.", - "empty": "Aún no hay claves API. Crea una para empezar.", - "anyIp": "Cualquier IP", - "never": "Nunca", - "count_one": "{{count}} clave · página {{page}} de {{pages}}", - "count_other": "{{count}} claves · página {{page}} de {{pages}}", - "enterprise": { - "title": "Las claves API son una función Enterprise", - "body": "Emite, restringe y rota claves API para acceso programático a la API de UTMStack. Esta capacidad está disponible en la edición Enterprise.", - "upgrade": "Actualizar a Enterprise", - "manageLicense": "Gestionar tu licencia" - }, - "col": { - "name": "Nombre", - "allowedIps": "IPs permitidas", - "created": "Creada", - "lastRotated": "Última rotación", - "expires": "Expira", - "status": "Estado", - "actions": "Acciones" - }, - "status": { - "active": "Activa", - "expiring": "Por expirar", - "expired": "Expirada" - }, - "action": { - "rotate": "Rotar", - "edit": "Editar", - "delete": "Eliminar" - }, - "dialog": { - "editTitle": "Editar clave API", - "newTitle": "Nueva clave API", - "name": "Nombre", - "namePlaceholder": "ci-pipeline", - "allowedIps": "IPs permitidas", - "allowedIpsHint": "Separadas por comas. Deja vacío para permitir cualquier IP.", - "expires": "Expira", - "expiresHint": "Deja vacío para una clave que nunca expira.", - "secretNote": "El token secreto se muestra una sola vez, justo tras la creación. Cópialo entonces — no se puede recuperar después (solo rotar).", - "cancel": "Cancelar", - "saving": "Guardando…", - "saveChanges": "Guardar cambios", - "createKey": "Crear clave" - }, - "confirm": { - "deleteTitle": "Eliminar clave API", - "rotateTitle": "Rotar clave API", - "deleteBody": "¿Eliminar {{name}}? Cualquier cliente que la use perderá el acceso de inmediato. Esto no se puede deshacer.", - "rotateBody": "¿Rotar {{name}}? Se emite un nuevo secreto y el actual deja de funcionar de inmediato. El nuevo token se muestra una sola vez.", - "cancel": "Cancelar", - "working": "Procesando…", - "delete": "Eliminar", - "rotate": "Rotar" - }, - "reveal": { - "title": "Clave API creada", - "note": "Copia este secreto ahora — para {{name}}. No se volverá a mostrar. Si lo pierdes, rota la clave.", - "copied": "Copiado", - "copy": "Copiar", - "done": "Listo" - }, - "toast": { - "updated": "Clave API actualizada", - "secretIssueFailed": "Clave creada, pero no se pudo emitir el secreto. Usa Rotar para obtener uno.", - "deleted": "Clave API eliminada" - }, - "error": { - "nameTaken": "Ya existe una clave API con ese nombre", - "enterpriseRequired": "Las claves API requieren la edición Enterprise", - "notFound": "Clave API no encontrada", - "invalidRequest": "Solicitud inválida", - "failed": "Operación fallida" - } - }, - "idp": { - "title": "Proveedores de identidad", - "subtitle": "Inicio de sesión único SAML 2.0 para tu organización.", - "add": "Agregar proveedor", - "enterprise": { - "title": "El SSO es una función Enterprise", - "body": "Conecta un proveedor de identidad SAML 2.0 (Entra ID, Okta, Google Workspace…) para que tu equipo inicie sesión con tu IdP. El inicio de sesión único está disponible en la edición Enterprise.", - "upgrade": "Actualizar a Enterprise" - }, - "loading": "Cargando proveedores de identidad…", - "loadFailed": "No se pudieron cargar los proveedores de identidad.", - "retry": "Reintentar", - "empty": { - "title": "No hay proveedores de identidad configurados", - "body": "Agrega un proveedor SAML 2.0 para que tu equipo inicie sesión con tu IdP corporativo." - }, - "card": { - "enable": "Habilitar", - "disable": "Deshabilitar", - "active": "Activo", - "disabled": "Deshabilitado", - "metadataUrl": "URL de metadatos", - "spEntityId": "SP Entity ID", - "spAcsUrl": "SP ACS URL", - "loginUrl": "URL de inicio de sesión", - "copy": "Copiar", - "edit": "Editar", - "delete": "Eliminar", - "jit": "Alta", - "jitOn": "crea cuentas en el primer acceso", - "sync": "Roles", - "syncOn": "se reaplican en cada acceso" - }, - "form": { - "addTitle": "Agregar proveedor de identidad", - "editTitle": "Editar proveedor de identidad", - "name": "Nombre", - "nameHint": "Único. Se usa en la URL de SSO.", - "providerType": "Tipo de proveedor", - "providerTypeHint": "Una etiqueta, p. ej. azure, okta, google.", - "metadataUrl": "URL de metadatos del IdP", - "spEntityId": "SP Entity ID", - "spAcsUrl": "SP ACS URL", - "certificate": "Certificado SP (PEM)", - "privateKey": "Llave privada SP (PEM)", - "privateKeyHintEdit": "Déjalo vacío para conservar la llave guardada.", - "privateKeyHintCreate": "Requerida. Se guarda cifrada; no se vuelve a mostrar.", - "privateKeyUnchanged": "•••••••• (sin cambios)", - "active": "Activo (mostrar en la página de inicio de sesión)", - "cancel": "Cancelar", - "saving": "Guardando…", - "save": "Guardar cambios", - "create": "Crear proveedor", - "issuer": "URL del emisor", - "issuerHint": "El descubrimiento se hace contra esta URL; el proveedor debe servir /.well-known/openid-configuration bajo ella.", - "clientId": "ID de cliente", - "redirectUrl": "URL de retorno", - "redirectUrlHint": "Registra exactamente esta URL en el proveedor.", - "host": "Servidor", - "port": "Puerto", - "startTls": "TLS", - "startTlsOn": "Usar StartTLS", - "bindDn": "DN de conexión", - "bindDnHint": "Una cuenta de servicio que pueda buscar en el directorio.", - "baseDn": "DN base", - "userFilter": "Filtro de usuario", - "userFilterHint": "Debe contener %s, donde se sustituye la dirección escrita al entrar.", - "emailAttribute": "Atributo de correo", - "nameAttribute": "Atributo de nombre", - "groupAttribute": "Atributo de grupo", - "provisioning": "Cuentas y roles", - "provisioningHint": "Qué ocurre cuando entra alguien por quien responde el directorio.", - "jit": "Crear la cuenta en el primer acceso", - "defaultRole": "Rol por defecto", - "defaultRoleHint": "Se concede cuando ningún grupo casa. Sin él, un acceso sin coincidencia se rechaza.", - "noDefaultRole": "Ninguno", - "groupsAttribute": "Atributo de grupos", - "groupsAttributeHint": "Dónde pone el proveedor la pertenencia a grupos.", - "syncRoles": "Reaplicar roles en cada acceso", - "syncRolesHint": "Los roles que no estén en el mapeo se quitan, para que un cambio en el directorio llegue hasta aquí. Sin esto, una degradación no llega nunca.", - "mappings": "Grupo a rol", - "mappingsHint": "Un grupo del directorio a la izquierda, el rol que concede a la derecha.", - "addMapping": "Añadir", - "noMappings": "Sin mapeos. Todos reciben el rol por defecto.", - "groupPlaceholder": "Analistas SOC", - "pickRole": "Elige un rol", - "secret.saml": "Clave privada del SP", - "secret.oidc": "Secreto de cliente", - "secret.ldap": "Contraseña de conexión", - "secretHintCreate": "Se guarda cifrada y no se vuelve a mostrar.", - "secretHintEdit": "Déjalo en blanco para conservar la guardada.", - "secretUnchanged": "sin cambios", - "errors": { - "required": "Este campo es obligatorio.", - "url": "Debe ser una URL http(s) válida.", - "httpsUrl": "Debe ser una URL https válida.", - "hostname": "Introduce un host o IP sin esquema (p. ej. ldap.ejemplo.com).", - "port": "El puerto debe ser un número entero entre 0 y 65535.", - "pemCertificate": "No parece un certificado PEM (faltan -----BEGIN/END CERTIFICATE-----).", - "pemKey": "No parece una clave privada PEM (faltan -----BEGIN/END PRIVATE KEY-----).", - "userFilterPlaceholder": "El filtro debe contener %s, donde se sustituye la dirección de inicio de sesión.", - "userFilterUnbalanced": "Hay paréntesis desequilibrados: la búsqueda no devolverá nada.", - "nameFormat": "Usa letras, números, puntos, guiones o guiones bajos (máx. 64). Aparece en la URL de SSO, por lo que no admite espacios.", - "redirectUrl": "Debe ser una URL https válida, o una URL http de loopback (localhost / 127.0.0.1 / [::1]).", - "entityId": "Debe ser una URI válida, p. ej. https://utmstack.example.com/sp." - } - }, - "delete": { - "title": "Eliminar proveedor de identidad", - "body": "¿Eliminar {{name}}? Los usuarios ya no podrán iniciar sesión a través de él. Esto no se puede deshacer.", - "cancel": "Cancelar", - "deleting": "Eliminando…", - "confirm": "Eliminar" - }, - "toast": { - "enabled": "Proveedor habilitado", - "disabled": "Proveedor deshabilitado", - "created": "Proveedor de identidad creado", - "updated": "Proveedor de identidad actualizado", - "deleted": "Proveedor de identidad eliminado", - "paidPlan": "El SSO SAML requiere un plan de pago", - "enterpriseRequired": "El SSO requiere la edición Enterprise", - "notFound": "Proveedor de identidad no encontrado", - "invalid": "Configuración inválida", - "failed": "La operación falló" - }, - "providerType": { - "saml": "SAML 2.0", - "oidc": "OpenID Connect", - "ldap": "LDAP / Active Directory", - "comingSoon": "aún no disponible" - } - }, - "userAuditor": { - "title": "Auditor de usuarios", - "subtitle": "Cuentas de Active Directory observadas en tus logs de seguridad de Windows — descubiertas a partir de eventos de creación, inicio de sesión y borrado.", - "export": "Exportar", - "accountsChip": "{{count}} cuentas", - "overview": { - "title": "Inventario de cuentas", - "active": "activas", - "disabled": "deshabilitadas", - "deleted": "borradas", - "seen24h": "{{count}} vistas en las últimas 24 horas", - "byDomain": "Por dominio" - }, - "views": { - "all": "Todas las cuentas", - "windows": "Windows", - "linux": "Linux", - "active": "Activas", - "disabled": "Deshabilitadas", - "deleted": "Borradas", - "service": "Cuentas de servicio", - "stale": "Inactivas (30d+)" - }, - "searchPlaceholder": "Buscar por nombre de cuenta o SID…", - "allTenants": "Todos los tenants", - "filters": { - "add": "Añadir filtro", - "clearAll": "Limpiar todo", - "filterValues": "Filtrar valores…", - "loadingValues": "Cargando valores…", - "noValues": "No se encontraron valores.", - "pickValue": "Elige un valor para añadir el filtro.", - "empty": "(vacío)", - "cancel": "Cancelar", - "addBtn": "Añadir" - }, - "filterFields": { - "status": "Estado de ciclo de vida" - }, - "ops": { - "is": "es" - }, - "refresh": "Actualizar", - "layout": { - "list": "Lista", - "cards": "Tarjetas" - }, - "list": { - "account": "Cuenta", - "identity": "Identidad", - "sid": "SID", - "status": "Estado", - "lastLogon": "Último inicio", - "lastSeen": "Última vez vista", - "tenant": "Tenant" - }, - "status": { - "active": "Activa", - "disabled": "Deshabilitada", - "deleted": "Borrada" - }, - "badge": { - "service": "servicio", - "stale": "inactiva" - }, - "empty": "Ninguna cuenta coincide con esta vista.", - "loadError": "No se pudieron cargar las cuentas de AD.", - "retry": "Reintentar", - "card": { - "lastLogon": "Último inicio" - }, - "pageInfo": "{{from}}–{{to}} de {{count}}", - "drawer": { - "tenantInline": "tenant {{id}}", - "serviceAccount": "cuenta de servicio", - "stale": "inactiva 30d+", - "viewInLogs": "Ver eventos en el Log Explorer", - "copySid": "Copiar SID", - "copyUid": "Copiar identidad", - "copied": "Copiado", - "identity": "Identidad", - "accountName": "Nombre de cuenta", - "domain": "Dominio", - "hostname": "Hostname", - "sid": "SID", - "uidNumber": "UID", - "machineId": "ID de máquina", - "tenant": "Tenant", - "adStatus": "Estado en AD", - "enabled": "Habilitada", - "disabled": "Deshabilitada", - "lifecycle": "Ciclo de vida", - "created": "Cuenta creada", - "lastLogon": "Último inicio de sesión", - "lastSeen": "Última vez vista en logs", - "deleted": "Cuenta borrada", - "noLifecycle": "Sin eventos de ciclo de vida." - }, - "relative": { - "justNow": "ahora mismo", - "minutesAgo": "hace {{count}}m", - "hoursAgo": "hace {{count}}h", - "daysAgo": "hace {{count}}d" - }, - "none": "—" - }, - "connectionKey": { - "title": "Clave de conexión", - "subtitle1": "La clave que los agentes presentan al registrarse en esta instancia.", - "subtitleEmphasis": "Solo se usa para la instalación de agentes", - "subtitle2": "— no para colectores, integraciones ni la API. La gestiona el agent-manager.", - "status": { - "label": "Estado", - "loading": "Cargando…", - "unavailable": "Agent-manager no disponible", - "active": "Activa", - "unavailableHint": "No se pudo contactar al agent-manager para leer la clave.", - "activeHint": "Los agentes pueden registrarse con esta clave." - }, - "token": { - "title": "Clave de conexión", - "subtitle": "Trata este valor como una credencial. Rotarla genera una nueva clave para futuras instalaciones de agentes — los agentes ya registrados siguen funcionando.", - "loadFailedTitle": "No se pudo cargar la clave de conexión", - "unavailableTitle": "Clave de conexión no disponible", - "loadFailedHint": "La clave la gestiona el agent-manager, que no respondió. Inténtalo de nuevo en un momento.", - "retry": "Reintentar", - "show": "Mostrar clave", - "hide": "Ocultar clave", - "copy": "Copiar", - "copied": "Copiado", - "regenerate": "Regenerar clave de conexión", - "confirmTitle": "¿Regenerar la clave?", - "confirmBody": "Las nuevas instalaciones de agentes necesitarán la nueva clave. Los agentes ya registrados seguirán funcionando. No se puede deshacer.", - "regenerating": "Regenerando…", - "confirmYes": "Sí, regenerar", - "cancel": "Cancelar" - }, - "security": { - "title": "Recomendaciones de seguridad", - "subtitle": "Buenas prácticas para proteger esta credencial.", - "rotateTitle": "Rota cada 90 días", - "rotateBody": "Programa una rotación periódica. UTMStack puede enviarte un recordatorio por correo cuando la clave tenga más de 90 días.", - "rotateAction": "Configurar recordatorio", - "secretTitle": "Guárdala como secreto", - "secretBody": "No la subas al control de versiones. Usa tu gestor de secretos (Vault, AWS SM, etc.) e inyéctala en el momento de la instalación.", - "auditTitle": "Audita quién la obtuvo", - "auditBody": "Cada obtención y rotación queda registrada en el journal de auditoría de la aplicación.", - "auditAction": "Ver journal de auditoría" - }, - "toast": { - "loadFailed": "No se pudo cargar la clave de conexión", - "rotated": "Clave de conexión rotada", - "rotateFailed": "No se pudo rotar la clave de conexión", - "copyFailed": "No se pudo copiar" - } - }, - "dataRetention": { - "title": "Retención de datos", - "subtitle": "Cuánto se guarda cada conjunto de datos y cuándo sus registros dejan de ocupar disco local.", - "loading": "Cargando…", - "loadFailed": "No se pudo leer el almacén.", - "retry": "Reintentar", - "datasets": { - "logs": "Logs", - "alerts": "Alertas", - "statistics": "Estadísticas de ingesta" - }, - "holding": "{{documents}} registros · {{size}}", - "since": "desde {{date}}", - "diskUsed": "Disco al {{pct}}%", - "keep": "Eliminar después de", - "keepHint": "Un registro se elimina esos días después de ocurrir, esté donde esté guardado.", - "cold": "Mover a almacenamiento frío tras", - "coldHint": "Los registros antiguos pasan al object storage y siguen siendo consultables. 0 los deja siempre en disco local.", - "coldUnavailable": "Configura el almacenamiento frío abajo para sacar los registros antiguos del disco local.", - "coldBeforeDelete": "Los registros deben moverse antes de eliminarse: usa menos días que la vida total, o 0.", - "tieredNote": "Este conjunto mueve registros a almacenamiento frío. Volver a solo disco local exige reconstruir la tabla, así que no se puede apagar aquí.", - "days": "días", - "save": "Guardar", - "saving": "Guardando…", - "toast": { - "saved": "Retención guardada", - "noPermission": "No tienes permiso para cambiar la retención", - "saveFailed": "No se pudo guardar la retención" - }, - "coldStorage": { - "title": "Almacenamiento frío", - "hint": "Un object storage que el almacén trata como un segundo disco más lento. Los registros antiguos se mueven allí y se consultan desde el mismo sitio: no es un archivo y no hay que restaurar nada.", - "active": "En uso", - "inactive": "Sin configurar", - "writtenNotReady": "El bucket está configurado pero el almacén no lo ha tomado. Comprueba que el despliegue comparte el directorio de configuración del almacén.", - "endpoint": "URL del bucket", - "accessKey": "Access key", - "secretKey": "Secret key", - "bucketLocked": "Las credenciales se pueden cambiar cuando quieras. El bucket no, una vez hay registros dentro: las partes ya movidas lo llevan.", - "enable": "Activar almacenamiento frío", - "update": "Actualizar credenciales", - "toast": { - "saved": "Almacenamiento frío configurado", - "failed": "No se pudo configurar el almacenamiento frío" - }, - "kind": "Tipo", - "kind_s3": "Almacén de objetos compatible con S3", - "kind_local": "Carpeta local o NFS", - "kind_azure": "Azure Blob Storage", - "accountUrl": "URL de la cuenta de almacenamiento", - "container": "Contenedor", - "accountName": "Nombre de la cuenta", - "accountKey": "Clave de la cuenta", - "useRole": "Usar el rol IAM del servidor en lugar de claves", - "s3Hint": "Funciona con AWS S3 y cualquier almacén compatible con S3: MinIO, Ceph, Wasabi, Cloudflare R2 o Google Cloud Storage (endpoint https://storage.googleapis.com// con claves HMAC).", - "localHint": "Los registros pasan a la carpeta montada en /mnt/utmstack-cold dentro del almacén de eventos: un directorio normal en la carpeta de datos, o un recurso NFS montado en el host sobre /clickhouse/cold antes de iniciar el stack. No requiere credenciales.", - "changeWarning": "No migramos los datos que ya están en el destino actual. Se quedan allí y dejan de poder consultarse desde aquí hasta que copies a mano el destino anterior al nuevo." - }, - "forbidden": { - "title": "Esta página es de la plataforma", - "body": "La retención se aplica a las tablas que comparten todos los tenants, así que solo un administrador de plataforma puede verla o cambiarla. Pídeselo a uno, o entra con una cuenta de plataforma." - } - }, - "languageSettings": { - "title": "Idioma de la plataforma", - "subtitle": "Idioma por defecto para las pantallas pre-login, los correos del sistema y los usuarios nuevos. Cada usuario puede elegir el suyo en su perfil.", - "label": "Idioma por defecto", - "hint": "Se usa cuando un usuario no ha elegido su propio idioma.", - "save": "Guardar", - "saving": "Guardando…", - "saved": "Idioma de la plataforma actualizado", - "loadError": "No se pudo cargar la configuración de idioma", - "saveError": "No se pudo guardar la configuración de idioma" - }, - "branding": { - "title": "Marca", - "subtitle": "Personaliza UTMStack con la identidad de tu organización — se aplica en todo: la pantalla de login, el menú lateral, los correos y los informes.", - "enterpriseRequired": "El white-label es una función Enterprise.", - "manageLicense": "Gestionar licencia", - "enable": { - "title": "White-label", - "description": "Reemplaza la marca UTMStack por la tuya en toda la plataforma.", - "label": "Activar white-label" - }, - "identity": { - "title": "Identidad", - "productName": "Nombre del producto", - "productNameHint": "Se muestra en la barra de título, el menú lateral y los correos.", - "accent": "Color de acento", - "accentHint": "Color primario de botones, enlaces y estados activos.", - "custom": "Color personalizado" - }, - "logos": { - "title": "Logos", - "hint": "PNG, SVG, WEBP, JPG o ICO. Hasta 5 MB.", - "logo": "Logo (claro)", - "logoDark": "Logo (oscuro)", - "favicon": "Favicon" - }, - "reports": { - "title": "Recursos de informes", - "hint": "Incrustados en los informes PDF generados.", - "reportLogo": "Logo de informe", - "reportCover": "Portada de informe" - }, - "asset": { - "upload": "Subir", - "replace": "Reemplazar" - }, - "save": "Guardar cambios", - "saving": "Guardando…", - "saved": "Marca actualizada", - "saveError": "No se pudo guardar la marca", - "uploaded": "Imagen subida", - "uploadError": "No se pudo subir la imagen", - "loadError": "No se pudo cargar la marca", - "enterprise": { - "title": "La marca blanca es una función Enterprise", - "body": "Sustituye el nombre del producto, el logotipo y la portada de los informes por los tuyos, para que el panel y todo lo que genera lleven tu marca y no la de UTMStack.", - "upgrade": "Actualizar a Enterprise" - }, - "restore": "Restaurar los valores de UTMStack", - "restored": "Marca restaurada a los valores de UTMStack" - }, - "emailConfig": { - "title": "Configuración de correo", - "subtitle": "Servidor SMTP usado para enviar notificaciones de alertas, informes y correos de cuenta.", - "server": { - "title": "Servidor SMTP", - "host": "Host", - "hostHint": "Nombre del servidor SMTP.", - "port": "Puerto", - "encryption": "Cifrado", - "username": "Usuario", - "password": "Contraseña", - "passwordSetHint": "Hay una contraseña guardada. Déjalo vacío para conservarla, o escribe una nueva para cambiarla." - }, - "encryptionOpt": { - "TLS": "TLS", - "SSL": "SSL", - "NONE": "Ninguno" - }, - "sender": { - "title": "Remitente", - "from": "Dirección de origen", - "fromHint": "Dirección desde la que se envían los correos.", - "organization": "Nombre de la organización", - "organizationHint": "Se muestra en los correos de notificación de alertas e incidentes.", - "baseUrl": "URL base", - "baseUrlHint": "URL pública de esta instancia, usada en los enlaces de los correos." - }, - "test": { - "button": "Enviar prueba", - "sending": "Enviando…", - "sentTo": "Se enviará un correo de prueba a {{email}}.", - "success": "Correo de prueba enviado a {{email}}", - "fail": "No se pudo enviar el correo de prueba", - "fromRequired": "Define una dirección de origen antes de probar" - }, - "save": "Guardar cambios", - "saving": "Guardando…", - "saved": "Configuración de correo guardada", - "saveError": "No se pudo guardar la configuración", - "loadError": "No se pudo cargar la configuración", - "recipients": { - "alertsTitle": "Destinatarios de alertas", - "incidentsTitle": "Destinatarios de incidentes", - "to": "Para", - "cc": "CC", - "alertsHelper": "Direcciones avisadas cuando se generan nuevas alertas. Si lo dejas vacío, las alertas no se envían por correo.", - "incidentsHelper": "Direcciones avisadas cuando se crea un incidente. Si lo dejas vacío, los incidentes no se envían por correo.", - "add": "Añadir" - } - }, - "dateFormat": { - "title": "Fecha y hora", - "subtitle": "Cómo se muestran los timestamps en toda la plataforma. Los logs siempre se almacenan en UTC.", - "timezone": { - "title": "Zona horaria", - "hint": "Los timestamps se muestran en esta zona horaria. Los datos se almacenan en UTC.", - "system": "Predeterminado del navegador", - "now": "Ahora: {{value}}" - }, - "format": { - "title": "Formato de fecha", - "hint": "Estilo usado para fechas y horas." - }, - "styles": { - "short": "Corto", - "medium": "Medio", - "long": "Largo", - "full": "Completo" - }, - "save": "Guardar cambios", - "saving": "Guardando…", - "saved": "Configuración de fecha guardada", - "saveError": "No se pudo guardar la configuración", - "loadError": "No se pudo cargar la configuración" - }, - "about": { - "title": "Acerca de esta instancia", - "subtitle": "Versión, licencia y estado del sistema de este despliegue de UTMStack.", - "loading": "Cargando información de la instancia…", - "edition": { - "enterprise": "Enterprise", - "community": "Community" - }, - "fields": { - "hostname": "Servidor", - "instanceId": "ID de instancia", - "noInstanceMeta": "No hay metadatos de la instancia disponibles." - }, - "license": { - "title": "Licencia", - "enterpriseMssp": "Enterprise · MSSP", - "datasources": "Datasources", - "communityLimited": "Límite Community", - "unlimited": "Ilimitado", - "expires": "Expira", - "managedNote": "La edición, los límites de datasources y la carga de licencia se gestionan en la página de Licencia.", - "view": "Ver licencia", - "ingest": "Volumen de ingesta", - "notMetered": "Sin medición", - "gbPerMonth": "{{gb}} GB/mes" - }, - "services": { - "backend": { - "name": "Backend API", - "desc": "Gateway REST, autenticación y orquestación de módulos." - }, - "opensearch": { - "name": "OpenSearch", - "desc": "Almacenamiento de logs y eventos.", - "detail": "{{nodes}} nodos · {{shards}} shards" - }, - "unreachable": "Inaccesible" - }, - "status": { - "up": "Saludable", - "degraded": "Degradado", - "down": "Caído", - "unknown": "Desconocido" - }, - "health": { - "title": "Estado del sistema", - "allHealthy": "Todos los servicios saludables. Actualiza para revisar.", - "issues_one": "{{count}} servicio necesita atención.", - "issues_other": "{{count}} servicios necesitan atención.", - "refresh": "Actualizar" - }, - "usage": { - "title": "Fuentes de datos", - "subtitle": "Fuentes de datos configuradas en esta instalación.", - "ofUnlimited": "de ilimitado", - "ofLimit": "de {{limit}}", - "overLimit": "Por encima del límite licenciado — los datos que excedan el tope están en riesgo.", - "configured": "configuradas" - }, - "support": { - "title": "Soporte", - "docs": "Documentación", - "repo": "Repositorio en GitHub", - "issues": "Reportar un problema", - "website": "utmstack.com" - }, - "legal": { - "title": "Legal", - "license": "Licencia", - "security": "Divulgación de seguridad", - "copyright": "© {{year}} UTMStack. Todos los derechos reservados." - } - }, - "logExplorer": { - "title": "Explorador de logs", - "eventsIn": "eventos en", - "searching": "Buscando…", - "query": { - "allDataTypes": "Todos los tipos de dato", - "dataTypes": "Tipos de dato", - "exportCsv": "Exportar CSV", - "filterDataTypes": "Filtrar tipos de dato…", - "noDataTypes": "Sin tipos de dato", - "noDataTypesMatch": "Ningún tipo de dato coincide", - "noTextSearch": "Este origen no tiene campo de texto completo — filtra por campo", - "refresh": "Actualizar", - "run": "Ejecutar", - "search": "Buscar", - "searchPlaceholder": "Buscar en todos los campos…" - }, - "time": { - "15m": "Últimos 15 minutos", - "1h": "Última hora", - "6h": "Últimas 6 horas", - "24h": "Últimas 24 horas", - "7d": "Últimos 7 días", - "30d": "Últimos 30 días" - }, - "ops": { - "is": "es", - "isNot": "no es", - "contains": "contiene", - "exists": "existe", - "between": "entre", - "search": "busca", - "isOneOf": "es uno de", - "isNotOneOf": "no es ninguno de", - "doesNotContain": "no contiene", - "startsWith": "empieza con", - "doesNotStartWith": "no empieza con", - "endsWith": "termina con", - "doesNotEndWith": "no termina con", - "doesNotExist": "no existe", - "notBetween": "no está entre", - "greaterThan": "es mayor que", - "greaterThanOrEquals": "es mayor o igual que", - "lessThan": "es menor que", - "lessThanOrEquals": "es menor o igual que" - }, - "filters": { - "label": "Filtros", - "clearAll": "Limpiar todo" - }, - "fields": { - "title": "Campos", - "filterPlaceholder": "Filtrar campos…", - "none": "Sin campos", - "selected": "Campos seleccionados", - "available": "Campos disponibles", - "topValues_one": "Top {{count}} valor", - "topValues_other": "Top {{count}} valores", - "loading": "Cargando…", - "noValues": "Sin valores", - "addColumn": "Agregar como columna", - "removeColumn": "Quitar columna de la tabla", - "filterFor": "Filtrar por el valor", - "filterOut": "Excluir el valor", - "empty": "(vacío)" - }, - "results": { - "dataTypesFailed": "No se pudieron cargar los tipos de dato.", - "endOfResults": "Cargados los {{count}} eventos", - "loadingMore": "Cargando más…", - "message": "Mensaje", - "none": "Ningún log coincide con esta consulta.", - "removeColumn": "Quitar {{field}}", - "retry": "Reintentar", - "searchFailed": "La búsqueda falló.", - "searching": "Buscando…", - "source": "Origen", - "time": "Hora", - "scope": "Buscado en {{dataset}} · {{dataType}}.", - "searchAllDataTypes": "Buscar en todos los tipos" - }, - "detail": { - "fieldsCount_one": "{{count}} campo", - "fieldsCount_other": "{{count}} campos", - "copyJson": "Copiar JSON", - "copied": "Documento copiado", - "parsedFields": "Campos parseados", - "json": "JSON", - "filterFor": "Filtrar por", - "filterOut": "Excluir", - "surrounding": "Eventos alrededor", - "surroundingHint": "Mostrar eventos ±15 min alrededor de este, de la misma fuente" - }, - "view": { - "table": "Tabla", - "chart": "Gráfico" - }, - "chart": { - "aggregateOn": "Agregar por", - "per": "cada", - "topValues": "— top 20 valores", - "building": "Construyendo gráfico…", - "failed": "No se pudo construir el gráfico para este campo.", - "noData": "Sin datos para graficar." - }, - "intervals": { - "minute": "Minuto", - "hour": "Hora", - "day": "Día", - "week": "Semana", - "month": "Mes", - "quarter": "Trimestre", - "year": "Año" - }, - "toast": { - "exportFailed": "La exportación falló" - }, - "builder": { - "add": "Agregar filtro", - "filterValues": "Filtrar valores…", - "loadingValues": "Cargando valores…", - "noValues": "Sin valores.", - "cancel": "Cancelar", - "confirm": "Agregar", - "pickValue": "Pick a value to add the filter." - }, - "related": { - "nLogs_one": "{{count}} log", - "nLogs_other": "{{count}} logs", - "truncated": "Mostrando los primeros {{count}} logs relacionados (el conjunto completo es mayor)." - }, - "saved": { - "title": "Guardadas", - "empty": "Aún no hay búsquedas guardadas", - "saveCurrent": "Guardar búsqueda actual", - "save": "Guardar", - "namePlaceholder": "Nombre de la búsqueda", - "delete": "Eliminar", - "saved": "Guardada «{{name}}»", - "loading": "Cargando…", - "loadFailed": "No se pudieron cargar las búsquedas guardadas", - "saveFailed": "No se pudo guardar la búsqueda", - "deleteFailed": "No se pudo eliminar la búsqueda", - "unreadable": "No se pudo leer esa búsqueda guardada" - } - }, - "integrations": { - "title": "Integraciones", - "searchPlaceholder": "Buscar integraciones…", - "noMatch": "Ninguna integración coincide.", - "browseMarketplace": "Explorar marketplace", - "loading": "Cargando integraciones…", - "addCustom": { - "title": "Agregar integración personalizada", - "description": "Crear una nueva fuente personalizada", - "cta": "Crear" - }, - "tabs": { - "all": "Todas", - "agents": "Agentes", - "collectors": "Colectores", - "cloud": "Cloud", - "custom": "Personalizada" - }, - "kind": { - "agents & syslog": "Agente", - "device": "Colector", - "antivirus": "Colector", - "other": "Colector", - "custom": "Personalizada", - "cloud": "Cloud", - "utmstack modules": "Colector" - }, - "status": { - "configured": "Configurada", - "available": "Disponible" - }, - "card": { - "manage": "Gestionar →", - "setup": "Configurar →", - "eventsPerSec": "{{rate}} e/s", - "enabled": "Activado", - "setupShort": "Configurar" - }, - "drawer": { - "manage": "Gestionar", - "openDashboard": "Abrir panel", - "viewEvents": "Ver eventos", - "documentation": "Documentación", - "getInstallCmd": "Obtener comando de instalación", - "setupCollector": "Configurar colector", - "connect": "Conectar", - "configureCustom": "Configurar fuente personalizada", - "eventsRate": "{{rate}} eventos/s · {{count}} en 24h", - "manageRules": "Reglas", - "manageFilters": "Filtros" - }, - "setup": { - "agent": { - "howItWorksTitle": "Cómo funciona", - "howItWorksBody": "El agente {{name}} es un pequeño demonio que se ejecuta en el host y reenvía eventos locales a UTMStack sobre una conexión TLS autenticada. Se actualiza automáticamente e informa su estado de salud.", - "installTitle": "Instalar en {{name}}", - "installHint": "Ejecuta este comando en cada host {{name}} que desees monitorear. El token ya codifica tu workspace actual.", - "afterTitle": "Qué verás después de instalar", - "after1": "El host aparece bajo Fuentes de datos dentro de ~60 segundos después de que inicie el agente.", - "after2": "La telemetría comienza a fluir hacia el Log Explorer, limitada a tu workspace.", - "after3": "El agente auto-reporta CPU / memoria / estado del disco a UTMStack.", - "actionLabel": "Acción", - "platformLabel": "Plataforma", - "optionsLabel": "Opciones", - "skipCertValidation": "No validar el certificado TLS (servidor autofirmado)", - "noRemoteControl": "Deshabilitar la ejecución remota de comandos en este host", - "loadingToken": "Cargando token…", - "actions": { - "install": "Instalar", - "uninstall": "Desinstalar" - }, - "prereqTitle": "Requisitos previos a la instalación", - "prereqBody": "El agente de UTMStack se comunica con el servidor a través de los siguientes puertos. Asegúrese de que estén abiertos entre el host y UTMStack antes de instalar:", - "sensitiveWarning": "El comando siguiente contiene un token de inscripción sensible — no lo comparta.", - "uninstall": { - "title": "Desinstalar el agente", - "body": "Ejecute esto en el host para detener y eliminar el agente de UTMStack y sus servicios. Utiliza la plataforma seleccionada anteriormente." - }, - "macCompat": "Requiere macOS 11 (Big Sur) o posterior en Apple Silicon (M1/M2/M3 o más reciente). Los Mac basados en Intel no son compatibles." - }, - "collector": { - "howItWorksTitle": "Cómo funciona", - "howItWorksBody": "{{name}} no ejecuta un agente de UTMStack. En su lugar, instalas el colector de UTMStack en algún lugar de la red que tanto tu dispositivo {{name}} como UTMStack puedan alcanzar. {{name}} envía syslog al colector, el colector analiza, normaliza y reenvía eventos a UTMStack.", - "step1Title": "1 · Instalar el colector de UTMStack", - "step1Hint": "Ejecutar en un host Linux con acceso de red desde el dispositivo {{name}}.", - "step2Title": "2 · Configurar {{name}} para enviar syslog", - "step2Hint": "En el dispositivo {{name}}, apunta el reenvío de syslog a la dirección del colector en {{port}}.", - "vendorDocs": "Ver instrucciones específicas del proveedor", - "step3Title": "3 · Verificar", - "step3Body": "Dentro de algunos minutos deberías ver eventos de {{name}} bajo source: {{source}} en Log Explorer, y una nueva entrada en Fuentes de datos.", - "forwarder": { - "intro": { - "title": "Cómo funciona", - "body": "Los registros fluyen desde {{source}} hacia el UTMStack Collector, que los transmite de forma segura a UTMStack para correlación y alertas. No se instala nada en {{source}} — solo el Collector necesita ejecutarse en un host de tu red." - }, - "diagram": { - "sourceSub": "tus registros", - "forwarder": "Collector", - "forwarderSub": "escucha en {{port}}", - "utmstack": "UTMStack", - "utmstackSub": "alertas y correlación", - "flow1": "registros", - "flow2": "seguro" - }, - "noInstall": "No se instala nada en {{source}} — solo redirige sus registros al Collector.", - "install": { - "title": "Instalar el UTMStack Collector", - "body": "El Collector es un servicio Linux que recibe registros de tus dispositivos y los envía a UTMStack. Un solo Collector gestiona múltiples integraciones al mismo tiempo.", - "reuse": "¿Ya tienes un Collector en ejecución? Omite este paso — apunta {{source}} al existente usando el host y puerto indicados abajo." - }, - "tls": { - "title": "Opcional — Habilitar cifrado TLS", - "intro": "Por defecto el listener acepta TCP/UDP sin cifrar. Para cifrar el tráfico syslog en tránsito, carga primero tus certificados y luego rehabilita el listener con el protocolo tls.", - "step1": "1 · Cargar tu certificado y clave (una vez por Collector)", - "step1Note": "Puedes agregar un certificado CA como tercer argumento. Si se omite, se usa el certificado hoja como CA.", - "step2": "2 · Rehabilitar el listener con TLS" - }, - "httpsCerts": { - "title": "Carga el certificado TLS en el Collector", - "body": "Esta integración usa un listener HTTPS en el puerto {{port}}, por lo que el Collector necesita un certificado y una clave cargados antes de habilitarla:" - }, - "uninstall": { - "title": "Opcional — Desinstalar el Collector", - "body": "Ejecuta este comando en el host donde está instalado el Collector para detener el servicio y eliminar todos sus archivos." - }, - "instanceHeader": { - "title": "Cabecera de autorización", - "body": "Incluye esta cabecera Authorization en cada solicitud que envíes a la instancia. El secreto de la clave API solo se muestra una vez al generarla — cópialo entonces y pégalo en lugar del marcador de posición de abajo.", - "tabSimple": "Simple", - "tabBatch": "Lote" - }, - "manualCommand": { - "title": "Optional — Enable via the command line instead", - "intro": "Prefer the terminal? SSH into the Collector host and run the command below — it matches whatever protocol and port you have selected above.", - "certStep": "1 · Load your certificate and key (once per Collector)", - "enableStep": "2 · Enable the integration" - } - }, - "cisco": { - "source": "Cisco ASA", - "step1": { - "title": "Habilitar el listener Cisco ASA en el Collector", - "body": "En el host donde está instalado el Collector, ejecuta este comando para abrir el listener de registros Cisco ASA:", - "note": "Para usar TCP en lugar de UDP, reemplaza udp por tcp en el comando anterior." - }, - "step2": { - "title": "Configurar Cisco ASA para reenviar registros", - "body": "En tu Cisco ASA, habilita syslog y apúntalo al host del Collector en el puerto {{port}}. Ejecuta estos comandos en modo EXEC privilegiado (reemplaza con el nombre de tu interfaz interna o de gestión):" - } - }, - "ciscoSwitch": { - "source": "Cisco Switch", - "step1": { - "title": "Habilitar el listener Cisco Switch en el Collector", - "body": "En el host donde está instalado el Collector, ejecuta este comando para abrir el listener de registros Cisco Switch:", - "note": "Para usar TCP en lugar de UDP, reemplaza udp por tcp en el comando anterior." - }, - "step2": { - "title": "Configurar el switch para reenviar registros", - "body": "En modo EXEC privilegiado de tu Cisco switch, habilita syslog y apúntalo al host del Collector en el puerto {{port}}:" - } - }, - "ciscoMeraki": { - "source": "Cisco Meraki", - "step1": { - "title": "Habilitar el listener Cisco Meraki en el Collector", - "body": "En el host donde está instalado el Collector, ejecuta este comando para abrir el listener de registros Cisco Meraki:", - "note": "Para usar TCP en lugar de UDP, reemplaza udp por tcp en el comando anterior." - }, - "step2": { - "title": "Configurar Meraki para reenviar registros", - "body": "En el Dashboard de Meraki, ve a Network-wide → Configure → General, desplázate a la sección Reporting y agrega un servidor syslog con la IP del Collector y el puerto {{port}}. Selecciona todos los roles que deseas reenviar." - } - }, - "ciscoFirepower": { - "source": "Cisco Firepower", - "step1": { - "title": "Habilitar el listener Cisco Firepower en el Collector", - "body": "En el host donde está instalado el Collector, ejecuta este comando para abrir el listener de registros Cisco Firepower:", - "note": "Para usar TCP en lugar de UDP, reemplaza udp por tcp en el comando anterior." - }, - "step2": { - "title": "Configurar Firepower para reenviar registros", - "body": "En Firepower Management Center (FMC), ve a Devices → Platform Settings, edita o crea una política y navega a Syslog → Syslog Servers. Agrega la IP del Collector con el puerto {{port}} (UDP), asigna la política a tus dispositivos y despliega." - } - }, - "office365": { - "intro": { - "title": "Cómo funciona", - "body": "UTMStack se conecta a Microsoft 365 usando una app registrada en Azure AD y consulta la API de Actividad de Gestión de Office 365 para obtener eventos de auditoría y seguridad. No se instala ningún agente en tu tenant.", - "diagram": { - "source": "eventos de auditoría y seguridad", - "edge": "Management API", - "utmstackSub": "correlación y alertas" - }, - "note": "UTMStack solo requiere permisos de lectura — no se solicitan permisos de escritura." - }, - "appSection": "Registro de aplicación en Azure", - "steps": { - "azurePortal": { - "title": "Abrir Microsoft Entra ID", - "body": "Abre el Portal de Azure (portal.azure.com) y haz clic en Microsoft Entra ID." - }, - "appRegistrations": { - "title": "Ir a Registros de aplicaciones", - "body": "En el menú izquierdo, haz clic en Registros de aplicaciones." - }, - "registerApp": { - "title": "Registrar una nueva aplicación", - "body": "Haz clic en Nuevo registro. Nómbrala UTMStack O365 Agent, selecciona Solo cuentas en este directorio organizacional (Inquilino único) y haz clic en Registrar." - }, - "clientSecret": { - "title": "Crear un secreto de cliente", - "body": "Ve a Certificados y secretos → Nuevo secreto de cliente. Añade una descripción, establece el vencimiento en 730 días (24 meses) y haz clic en Agregar.", - "copyNote": "Copia el Valor del secreto inmediatamente — solo se muestra una vez y no se puede recuperar después." - }, - "apiPermissions": { - "title": "Agregar permisos de Office 365 Management API", - "body": "Ve a Permisos de API → Agregar un permiso y busca Office 365 Management APIs." - }, - "activityFeed": { - "title": "Conceder permisos de ActivityFeed", - "body": "Selecciona Permisos de aplicación y añade ActivityFeed.Read y ActivityFeed.ReadDlp. Haz clic en Conceder consentimiento de administrador y confirma." - }, - "graphPermissions": { - "title": "Agregar permisos de Microsoft Graph", - "body": "De vuelta en Agregar un permiso, haz clic en Microsoft Graph." - }, - "delegatedPermissions": { - "title": "Agregar permisos delegados de SecurityAlert", - "body": "Selecciona Permisos delegados y añade SecurityAlert.Read.All y SecurityAlert.ReadWrite.All. Haz clic en Conceder consentimiento de administrador y confirma." - }, - "appPermissions": { - "title": "Agregar permisos de aplicación de SecurityAlert", - "body": "Selecciona Permisos de aplicación y añade SecurityAlert.Read.All y SecurityAlert.ReadWrite.All. Haz clic en Conceder consentimiento de administrador y confirma." - }, - "noteIds": { - "title": "Copiar los IDs de la aplicación", - "body": "Ve a la Información general de la app y copia el ID de aplicación (cliente) y el ID de directorio (inquilino). También necesitas el valor del secreto copiado en el paso 4." - } - }, - "credentialsSection": "Credenciales", - "credentials": { - "title": "Conectar tu tenant de Microsoft 365", - "body": "Introduce los datos de los pasos anteriores. UTMStack verifica las credenciales antes de guardarlas. Puedes añadir múltiples grupos de configuración." - }, - "fields": { - "tenantId": { - "label": "Tenant ID (ID de directorio)" - }, - "clientId": { - "label": "Client ID (ID de aplicación)" - }, - "clientSecret": { - "label": "Secreto de cliente" - }, - "cloudEnv": { - "label": "Entorno de nube (opcional)", - "hint": "Commercial (por defecto), GCC, GCCHigh o DoD" - } - } - }, - "github": { - "source": "GitHub", - "step1": { - "title": "Habilitar el listener de webhook de GitHub en el Collector", - "body": "En el host donde está instalado el Collector, ejecuta este comando para abrir el listener HTTPS de webhook para GitHub:", - "tokenNote": "El terminal imprimirá un token secreto — cópialo inmediatamente. No se volverá a mostrar." - }, - "certWarning": { - "title": "GitHub requiere un certificado TLS firmado por una CA", - "body": "GitHub solo entrega webhooks a endpoints HTTPS con un certificado emitido por una CA pública (los certificados auto-firmados son rechazados). Asegúrate de que el host del Collector tenga un certificado de dominio válido antes de registrar el webhook." - }, - "step2": { - "title": "Registrar el webhook en GitHub", - "body": "En tu repositorio u organización, ve a Settings → Webhooks → Add webhook y completa el formulario:", - "payloadUrl": "Payload URL", - "contentType": "Content type", - "secret": "Secret", - "secretHint": "Pega el token impreso por el Collector en el paso anterior.", - "events": "Which events", - "eventsHint": "Send me everything — o selecciona tipos de eventos específicos." - } - }, - "aix": { - "source": "Servidor AIX", - "step1": { - "title": "Habilitar el listener AIX en el Collector", - "body": "En el host donde está instalado el Collector, ejecuta este comando para abrir el listener de registros AIX:", - "note": "Para usar TCP en lugar de UDP, reemplaza udp por tcp en el comando anterior." - }, - "step2": { - "title": "Configurar AIX para reenviar registros", - "body": "En tu sistema AIX, configura el servicio syslog para redirigir sus registros al host del Collector en el puerto {{port}}. Consulta la documentación de IBM para la sintaxis exacta — varía entre versiones de AIX." - } - }, - "as400": { - "intro": { - "title": "Cómo funciona", - "body": "El Colector AS/400 es un servicio Linux que se conecta directamente a tus sistemas AS/400 (IBM i) y extrae entradas del diario de seguridad, luego las envía de forma segura a UTMStack para correlación y alertas.", - "note": "No se instala nada en el AS/400 — el Colector se ejecuta en un host Linux que tenga acceso de red a tus sistemas AS/400.", - "diagram": { - "source": "tus diarios", - "edge1": "diarios", - "collector": "Colector AS/400", - "collectorSub": "extrae del AS/400", - "edge2": "seguro", - "utmstackSub": "alertas y correlación" - } - }, - "install": { - "title": "Instalar el Colector AS/400", - "body": "Ejecuta este comando en un host Linux que pueda alcanzar tanto UTMStack como tus sistemas AS/400 por la red.", - "reuse": "¿Ya tienes el Colector AS/400 instalado? Omite este paso — solo agrega tus servidores al archivo de configuración en el siguiente paso." - }, - "configure": { - "title": "Agregar tus servidores AS/400", - "body": "Edita as400-config.yaml en el directorio de instalación del colector y agrega cada sistema AS/400 que desees monitorear:", - "note": "Puedes listar múltiples servidores. El colector vigila este archivo y recarga automáticamente al guardar — sin necesidad de reinicio." - }, - "journal": { - "title": "Habilitar el diario de auditoría en AS/400", - "body": "En cada sistema AS/400, asegúrate de que el diario de auditoría de seguridad QAUDJRN esté activo. Consulta la documentación de IBM para los pasos exactos — el procedimiento varía entre versiones de IBM i." - }, - "uninstall": { - "title": "Opcional — Desinstalar el Colector", - "body": "Ejecuta este comando en el host donde está instalado el Colector AS/400 para detener el servicio y eliminar todos los archivos." - } - }, - "bitdefender": { - "intro": { - "title": "Cómo funciona", - "body": "UTMStack se conecta a Bitdefender GravityZone usando tu clave API para configurar el Event Push Service. GravityZone envía entonces los eventos de seguridad directamente a UTMStack para correlación y alertas.", - "diagram": { - "source": "eventos de endpoints", - "edge": "Event Push Service", - "utmstackSub": "alertas y correlación" - }, - "note": "No se instala nada en GravityZone — UTMStack se registra como destino de push usando credenciales de API de solo lectura." - }, - "whitelist": { - "title": "Añadir IPs de Bitdefender a la whitelist", - "body": "Las siguientes IPs de Bitdefender GravityZone deben estar permitidas en tu firewall en el puerto 8000 para que el Event Push Service pueda alcanzar UTMStack:", - "note": "Añade estas IPs a tu firewall o grupo de seguridad antes de completar la configuración." - }, - "apiSection": "Obtener credenciales API", - "api": { - "myAccount": { - "title": "Abrir Mi Cuenta", - "body": "En la consola de Bitdefender GravityZone, haz clic en My Account." - }, - "accessUrl": { - "title": "Anotar la Access URL", - "body": "Desplázate hasta la sección Control Center API y guarda la Access URL — la introducirás en el formulario de credenciales. Luego abre la sección de claves API y haz clic en Add." - }, - "createKey": { - "title": "Crear una clave API", - "body": "Escribe una descripción para la clave API, selecciona la opción Event Push Service API y haz clic en Save. Copia la clave generada." - } - }, - "companySection": "Obtener IDs de empresa", - "company": { - "myCompany": { - "title": "Abrir Mi Empresa", - "body": "En la consola de GravityZone, haz clic en My Company." - }, - "licensing": { - "title": "Anotar los IDs de empresa", - "body": "Abre la sección Licensing y guarda los Company IDs que quieres monitorizar — introdúcelos separados por comas en el formulario de credenciales." - } - }, - "credentials": { - "title": "Introducir credenciales", - "body": "Rellena la Access URL, la clave API, la IP pública de UTMStack (donde GravityZone enviará los eventos) y los IDs de empresa a monitorizar. UTMStack verifica las credenciales antes de guardarlas." - }, - "fields": { - "accessUrl": { - "label": "Access URL de GravityZone" - }, - "connectionKey": { - "label": "Clave API" - }, - "utmPublicIP": { - "label": "IP pública de UTMStack" - }, - "companyIds": { - "label": "IDs de empresa (separados por comas)" - } - } - }, - "netflow": { - "source": "Dispositivo de red", - "step1": { - "title": "Habilitar el listener de NetFlow en el Collector", - "body": "En el host donde está instalado el Collector, ejecuta este comando para abrir el colector NetFlow en el puerto 2055:", - "note": "NetFlow usa solo UDP — TCP y TLS no son compatibles con este protocolo." - }, - "step2": { - "title": "Configurar el dispositivo para exportar NetFlow", - "body": "Apunta la exportación de NetFlow en tu router o firewall al host del Collector en el puerto {{port}} UDP. El ejemplo siguiente es para Cisco IOS — consulta la documentación de tu fabricante para otras plataformas:", - "note": "Reemplaza con el nombre de la interfaz donde se debe monitorizar el tráfico (p.ej. GigabitEthernet0/0). Aplica ingress/egress en cada interfaz relevante." - } - }, - "sophos": { - "intro": { - "title": "Sophos Central — Plugin API", - "body": "Sophos Central proporciona APIs seguras para recuperar datos de eventos y alertas. UTMStack se conecta a esas APIs para centralizar la monitorización y mejorar la visibilidad de seguridad — sin agente ni collector.", - "diagram": { - "source": "API de Sophos Central", - "edge": "HTTPS API", - "utmstackSub": "Ingesta y correlaciona" - }, - "note": "UTMStack consulta la API de Sophos Central periódicamente. Asegúrate de que las credenciales que crees tengan acceso de lectura a eventos y alertas." - }, - "apiSection": "Generar credenciales API en Sophos Central", - "steps": { - "apiCredentials": { - "title": "Abrir la gestión de credenciales API", - "body": "En Sophos Central Admin, navega a Global Settings → API Credentials Management." - }, - "addCredential": { - "title": "Crear una nueva credencial", - "body": "Haz clic en Add Credential. Proporciona un Nombre y una Descripción, selecciona el Rol apropiado y haz clic en Add." - }, - "copyIds": { - "title": "Copiar el Client ID y el Client Secret", - "body": "Copia el Client ID y el Client Secret y guárdalos en un lugar seguro.", - "secretNote": "El Client Secret solo se muestra una vez. Guárdalo antes de cerrar este diálogo." - } - }, - "credentialsSection": "Conectar con UTMStack", - "credentials": { - "title": "Añadir credenciales de Sophos Central", - "body": "Introduce las credenciales que acabas de crear. Puedes añadir más de una cuenta de Sophos haciendo clic en Añadir grupo de configuración." - }, - "fields": { - "clientId": { - "label": "Client ID" - }, - "apiKey": { - "label": "Client Secret / API Key" - } - } - }, - "mikrotik": { - "source": "Router MikroTik", - "step1": { - "title": "Habilitar el listener de MikroTik en el Collector", - "body": "En el host donde está instalado el Collector, ejecuta este comando para abrir el listener syslog de MikroTik:", - "note": "Para usar TCP en lugar de UDP, reemplaza udp por tcp en el comando anterior." - }, - "step2": { - "title": "Configurar MikroTik para reenviar registros", - "body": "En el router MikroTik, crea una acción de logging remota apuntando al host del Collector en el puerto {{port}} y asígnala a los topics relevantes. Ejecuta lo siguiente desde la CLI de RouterOS (Terminal en Winbox):", - "note": "También puedes configurarlo desde Winbox: System → Logging → pestaña Actions (añade una acción Remote) → luego la pestaña Rules (añade reglas apuntando a la nueva acción)." - } - }, - "oracle": { - "source": "Servidor Oracle DB", - "step1": { - "title": "Habilitar la integración de Oracle en el Collector", - "body": "En el servidor donde está instalado el Collector, ejecuta el siguiente comando para comenzar a recibir logs de Oracle:", - "note": "El Collector comenzará a recibir eventos de syslog de Oracle en el puerto 7021." - }, - "step2": { - "title": "Configurar rsyslog en el servidor Oracle", - "body": "Crea el archivo de configuración de rsyslog:", - "editBody": "Abre el archivo con tu editor preferido y añade la siguiente configuración. Reemplaza BASEDIR con la ruta de instalación de Oracle (p. ej., /u01/app/oracle) y con la IP o nombre de host del Collector:", - "note": "Usa @@:7021 en lugar de @ si prefieres entrega por TCP." - }, - "step3": { - "title": "Reiniciar rsyslog", - "body": "Aplica la nueva configuración reiniciando el servicio rsyslog:" - }, - "step4": { - "title": "Validar la configuración", - "body": "Envía mensajes de prueba para verificar que UTMStack está recibiendo eventos de las tres fuentes de logs de Oracle:", - "note": "Abre el Explorador de Logs y busca el texto del mensaje de prueba anterior para confirmar que llegaron." - } - }, - "utmstack": { - "intro": { - "title": "Cómo funciona", - "body": "Esta integración automonitoriza tu despliegue de UTMStack. Un colector ligero instalado en el host de UTMStack lee los logs de los propios contenedores Docker de la plataforma y los envía de vuelta a UTMStack para correlación y alertas.", - "diagram": { - "source": "Logs de Docker", - "sourceSub": "Contenedores de UTMStack", - "edge1": "lee", - "collector": "Colector", - "collectorSub": "en el host", - "edge2": "ingesta", - "utmstackSub": "Correlaciona y alerta" - } - }, - "requirements": { - "title": "Solo se ejecuta en el host de UTMStack", - "body": "Esta integración solo se puede instalar en una instancia de UTMStack que ejecute Ubuntu o una distribución de la familia Red Hat. Instala el colector directamente en el servidor de UTMStack." - }, - "install": { - "title": "Instalar el colector", - "body": "En el host de UTMStack, elige tu sistema operativo y ejecuta el comando siguiente para descargar e instalar el colector de automonitorización:", - "sensitiveWarning": "Este comando contiene un token de conexión sensible. Trátalo como una contraseña y no lo compartas." - }, - "after": { - "title": "Qué verás después de instalar", - "item1": "El colector se registra y aparece en Fuentes de datos.", - "item2": "Los logs de los contenedores de UTMStack empiezan a fluir en menos de un minuto.", - "item3": "Los eventos se pueden buscar en el Explorador de Logs bajo el tipo de dato utmstack." - }, - "uninstall": { - "title": "Desinstalar el colector", - "body": "Para eliminar el colector de automonitorización del host de UTMStack, ejecuta:" - } - }, - "endpoint": { - "title": "Detalles de conexión", - "hint": "Configure {{name}} para reenviar sus registros al Collector usando el host y el puerto indicados a continuación." - }, - "syslog": { - "sections": { - "sendLogs": { - "title": "1 · Enviar registros a UTMStack", - "body": "Configure su dispositivo para enviar mensajes syslog por UDP (514) o TCP (514) al agente de UTMStack." - }, - "enableCollector": { - "title": "2 · Habilitar el colector syslog", - "body": "Habilite el colector de registros y la integración syslog en el archivo de configuración donde está instalado su agente de UTMStack." - }, - "activate": { - "title": "3 · Activar", - "body": "Active el módulo de UTMStack para que los eventos comiencen a fluir en el Log Explorer." - } - } - }, - "vmware": { - "source": "VMware ESXi", - "step1": { - "title": "Habilitar el listener de VMware en el Collector", - "body": "En el host donde está instalado el Collector, ejecute este comando para abrir el listener syslog de VMware ESXi. ESXi transmite por TCP:", - "note": "Para un canal cifrado use tls en lugar de tcp (cargue primero los certificados en el Collector)." - }, - "step2": { - "title": "Apuntar el syslog de ESXi al Collector", - "body": "Abra una sesión SSH/ESXi Shell en el host (o use el vSphere Client: Host → Configure → Advanced System Settings → Syslog.global.logHost). Establezca el loghost remoto en {{host}}:{{port}} y recargue la configuración:", - "note": "En vSphere puede en cambio establecer Syslog.global.logHost con el mismo valor tcp://host:port en lugar de ejecutar esxcli." - }, - "step3": { - "title": "Abrir el firewall de ESXi para syslog", - "body": "Permita el syslog saliente a través del firewall de ESXi para que el host pueda llegar al Collector:" - } - }, - "eset": { - "source": "ESET Protect", - "step1": { - "title": "Habilitar el listener de ESET en el Collector", - "body": "En el host donde está instalado el Collector, ejecute este comando para abrir el listener syslog de ESET:", - "note": "Para usar TCP en lugar de UDP, reemplace udp por tcp en el comando anterior." - }, - "console": { - "moreMenu": { - "title": "Abrir el menú More", - "body": "En la barra lateral de la consola ESET Protect, haga clic en el menú More." - }, - "serverConfig": { - "title": "Abrir la configuración del servidor", - "body": "En More, abra la sección Server settings (Server configuration)." - }, - "advanced": { - "title": "Expandir la configuración avanzada", - "body": "Haga clic en Advanced settings para expandir la lista completa de opciones de configuración." - }, - "syslog": { - "title": "Configurar el servidor Syslog", - "body": "Desplácese hasta Syslog server, habilite Export logs to Syslog y establezca el destino en el host del Collector en el puerto {{port}} (UDP). ESET envía LEEF/syslog, que el Collector ingiere como el tipo de datos antivirus-esmc-eset." - } - } - }, - "kaspersky": { - "source": "Kaspersky Security", - "step1": { - "title": "Habilitar el listener de Kaspersky en el Collector", - "body": "En el host donde está instalado el Collector, ejecute este comando para abrir el listener syslog de Kaspersky:", - "note": "Para usar TCP en lugar de UDP, reemplace udp por tcp en el comando anterior." - }, - "console": { - "consoleSettings": { - "title": "Abrir Console settings → Integration", - "body": "En la barra lateral del Kaspersky Security Center, abra Console settings y haga clic en el submenú Integration." - }, - "siem": { - "title": "Abrir la configuración de integración SIEM", - "body": "En Integration, seleccione SIEM y haga clic en el enlace Settings para abrir la configuración de exportación." - }, - "configure": { - "title": "Configurar la exportación SIEM", - "body": "Habilite la exportación y configure Kaspersky para enviar eventos en formato Splunk (CEF) al host del Collector en el puerto {{port}} (UDP). El Collector los ingiere como el tipo de datos antivirus-kaspersky." - } - } + "alerts": { + "title": "Alertas", + "matching": "{{count}} coincidentes", + "subtitle": "Prioriza lo que importa.", + "openNow": "abiertas ahora mismo.", + "view": { + "alerts": "Alertas", + "overview": "Resumen" }, - "webroot": { - "sections": { - "login": { - "title": "1 · Iniciar sesión en la consola de administración", - "body": "Inicie sesión en la consola de administración de Webroot. Se abre en la pestaña Sites." - }, - "openSettings": { - "title": "2 · Abrir Settings", - "body": "Haga clic en la pestaña Settings." - }, - "apiAccess": { - "title": "3 · Abrir API Access", - "body": "Desde la pestaña Subscriptions, haga clic en la pestaña API Access." - }, - "createCredential": { - "title": "4 · Crear una credencial de cliente", - "body": "Haga clic en New y complete el Name y la Description. Lea el acuerdo de SecureAnywhere Business Solution y Unity API, luego haga clic en Create." - }, - "noteClientSecret": { - "title": "5 · Copiar el ID de cliente y el secreto", - "body": "Guarde el Client ID de la lista y el Client Secret que se muestra solo una vez. Haga clic en \"I have made note of the client secret\" para confirmar." - }, - "fillForm": { - "title": "6 · Completar el formulario", - "body": "Proporcione el client ID y el client secret a UTMStack. Puede agregar más de un grupo de configuración de Webroot si es necesario." - }, - "activate": { - "title": "7 · Activar", - "body": "Active el módulo de UTMStack para que los eventos de Webroot comiencen a fluir." - } - } - }, - "sentinelOne": { - "source": "SentinelOne", - "step1": { - "title": "Habilitar el listener de SentinelOne en el Collector", - "body": "En el host donde está instalado el Collector, ejecute este comando para abrir el listener syslog de SentinelOne. SentinelOne transmite CEF por TCP:", - "note": "Para un canal cifrado use tls en lugar de tcp (cargue primero los certificados en el Collector)." - }, - "console": { - "settings": { - "title": "Abrir la configuración de SentinelOne", - "body": "En la barra lateral de la consola de administración de SentinelOne, haga clic en el menú Settings." - }, - "syslog": { - "title": "Configurar la integración Syslog", - "body": "Vaya a Integrations → Syslog y habilítelo. Establezca el host en {{host}} y el puerto en {{port}}, mantenga el formato como CEF, haga clic en Test para verificar la conexión, luego Save." - } - } + "toolbar": { + "searchPlaceholder": "Buscar por nombre de alerta…", + "allSeverities": "Todas las severidades", + "export": "Exportar CSV", + "refresh": "Actualizar" }, - "salesforce": { - "sections": { - "openSetup": { - "title": "1 · Abrir Setup", - "body": "Vaya a Setup y seleccione \"Setup for the current app\" en la parte superior derecha de la pantalla." - }, - "appManager": { - "title": "2 · Abrir App Manager", - "body": "Escriba \"App Manager\" en el cuadro de búsqueda rápida y seleccione App Manager." - }, - "newConnectedApp": { - "title": "3 · Crear una nueva Connected App", - "body": "En la pantalla del Lightning Experience App Manager, haga clic en \"New Connected App\" y complete los campos." - }, - "oauthSettings": { - "title": "4 · Habilitar OAuth Settings", - "body": "En la sección \"API (Enable OAuth Settings)\", marque \"Enable OAuth Settings\" y use https://login.salesforce.com/services/oauth2/success como Callback URL." - }, - "oauthScopes": { - "title": "5 · Agregar OAuth scopes", - "body": "Seleccione \"Access Connect REST API resources (chatter_api)\" en Selected OAuth Scopes." - }, - "save": { - "title": "6 · Guardar", - "body": "Guarde los cambios y seleccione Continue en la siguiente pantalla." - }, - "manageConsumer": { - "title": "7 · Abrir Manage Consumer Details", - "body": "Dentro de su Connected App, vaya a \"API (Enable OAuth Settings)\" y haga clic en \"Manage Consumer Details\" junto a Consumer Key and Secret." - }, - "copyCredentials": { - "title": "8 · Copiar la clave y el secreto del consumidor", - "body": "Verifique su identidad. El Consumer Key y el Consumer Secret aparecen en \"Consumer Details\". Cópielos con el botón Copy." - }, - "fillForm": { - "title": "9 · Completar el formulario", - "body": "Proporcione el Consumer Key, Consumer Secret, nombre de usuario y contraseña de Salesforce a UTMStack." - }, - "activate": { - "title": "10 · Activar", - "body": "Active el módulo de UTMStack para que los eventos de Salesforce comiencen a fluir." - } - } + "severity": { + "high": "Alta", + "medium": "Media", + "low": "Baja" }, - "iis": { - "sections": { - "enableModule": { - "title": "1 · Habilitar el módulo IIS de Filebeat", - "body": "En el host del agente de UTMStack, ejecute:\ncd \"C:\\Program Files\\UTMStack\\UTMStack Agent\\beats\\filebeat\\\" && filebeat modules enable iis" - }, - "configureModule": { - "title": "2 · Configurar el módulo IIS", - "body": "Edite C:\\Program Files\\UTMStack\\UTMStack Agent\\beats\\filebeat\\modules.d\\iis.yml como se muestra a continuación para apuntar a los directorios de registros IIS que desea enviar." - }, - "activate": { - "title": "3 · Activar", - "body": "Active el módulo de UTMStack para que los eventos de IIS comiencen a fluir." - } - } + "status": { + "open": "Abierta", + "in_review": "En revisión", + "completed": "Completada", + "auto": "Revisión automática" }, - "filebeat": { - "sections": { - "installRsyslog": { - "title": "1 · Instalar rsyslog", - "body": "Asegúrese de que rsyslog esté instalado en el host. Use el gestor de paquetes de su distribución (apt, dnf, yum)." - }, - "configureRsyslog": { - "title": "2 · Configurar rsyslog para reenviar a UTMStack", - "body": "Edite /etc/rsyslog.conf (o un archivo en /etc/rsyslog.d/) y añada una regla de reenvío que apunte al agente UTMStack por UDP o TCP en el puerto 514." - }, - "restartRsyslog": { - "title": "3 · Reiniciar rsyslog", - "body": "Reinicie el servicio rsyslog: sudo systemctl restart rsyslog" - }, - "enableCollector": { - "title": "4 · Habilitar el colector de logs de Linux", - "body": "Habilite el colector de logs y la integración Linux Logs en el archivo de configuración donde está instalado el agente UTMStack." - } - } + "statusTabs": { + "all": "Todas" }, - "json": { - "sections": { - "overview": { - "title": "1 · Usar el endpoint de ingesta HTTP/JSON", - "body": "UTMStack acepta eventos JSON arbitrarios por HTTPS. Envíe una solicitud POST con una lista de eventos; UTMStack los analiza y los enruta a través del parser configurado." - }, - "auth": { - "title": "2 · Autenticarse con un token de federación", - "body": "Obtenga un token de federación desde Configuración → Connection Key y envíelo como Bearer token en el encabezado Authorization." - } - }, - "endpoint": { - "title": "Endpoint de ingesta JSON", - "hint": "Use este formato de solicitud desde su aplicación o un cron job. El token es la clave de federación de Configuración → Connection Key." - } - }, - "ldap": { - "sections": { - "openServerManager": { - "title": "1 · Abrir Server Manager", - "body": "En el controlador de dominio AD, abra Server Manager." - }, - "addRoles": { - "title": "2 · Agregar roles y características", - "body": "Elija \"Agregar roles y características\" desde el menú Manage." - }, - "selectCertServices": { - "title": "3 · Seleccionar Active Directory Certificate Services", - "body": "En el paso Server Roles, seleccione Active Directory Certificate Services." - }, - "installServices": { - "title": "4 · Instalar el servicio de rol Certificate Authority", - "body": "En el paso Role Services, seleccione Certificate Authority y complete el asistente." - }, - "configureAdCs": { - "title": "5 · Configurar AD CS", - "body": "Tras la instalación, haga clic en la notificación para configurar AD CS y elija Certificate Authority como servicio de rol a configurar." - }, - "pickCaType": { - "title": "6 · Seleccionar el tipo de CA", - "body": "Elija Enterprise CA → Root CA → Create a new private key." - }, - "setValidity": { - "title": "7 · Establecer el período de validez del certificado", - "body": "Establezca un período de validez adecuado para su organización (5 años es lo habitual)." - }, - "confirm": { - "title": "8 · Confirmar e instalar", - "body": "Revise la configuración y haga clic en Configure para finalizar." - }, - "restart": { - "title": "9 · Reiniciar el controlador de dominio", - "body": "Reinicie el controlador de dominio para que LDAPS quede disponible en TCP 636." - }, - "activate": { - "title": "10 · Activar", - "body": "Active el módulo UTMStack para que los eventos de auditoría de AD comiencen a fluir." - } - } + "overview": { + "overTime": "Alertas en el tiempo", + "matchingAlerts": "alertas coincidentes", + "noData": "Sin datos.", + "bySeverity": "Por severidad", + "byStatus": "Por estado" }, - "vulnerabilities": { - "sections": { - "overview": { - "title": "1 · Acerca del escáner de vulnerabilidades", - "body": "El módulo de vulnerabilidades de UTMStack analiza los activos descubiertos a través del módulo Asset Management y compara su huella digital con la base de datos CVE." - }, - "scope": { - "title": "2 · Definir el alcance del escaneo", - "body": "Use el módulo Asset Management para registrar los hosts que desea escanear. El escáner de vulnerabilidades se ejecutará periódicamente sobre ellos." - }, - "activate": { - "title": "3 · Activar", - "body": "Active el módulo UTMStack para comenzar el escaneo." - } - } + "filters": { + "add": "Añadir filtro", + "clearAll": "Limpiar todo", + "filterValues": "Filtrar valores…", + "loadingValues": "Cargando valores…", + "noValues": "No se encontraron valores.", + "pickValue": "Elige un valor para añadir el filtro.", + "empty": "(vacío)", + "cancel": "Cancelar", + "addBtn": "Añadir" }, - "assetScanner": { - "sections": { - "overview": { - "title": "1 · Acerca de Asset Management", - "body": "El módulo Asset Management descubre e inventaría hosts, software y servicios en su red." - }, - "agentRequirement": { - "title": "2 · Requisito del agente", - "body": "El descubrimiento de activos utiliza agentes UTMStack que se ejecutan en hosts Linux, Windows o macOS. Instale el agente en los sistemas que desee inventariar." - }, - "activate": { - "title": "3 · Activar", - "body": "Active el módulo UTMStack para iniciar el descubrimiento de activos." - } - } + "ops": { + "CONTAIN": "contiene", + "IS": "es", + "IS_NOT": "no es", + "EXIST": "existe", + "DOES_NOT_EXIST": "no existe" }, - "fileIntegrity": { - "sections": { - "enableAuditPolicy": { - "title": "1 · Habilitar la auditoría de acceso a objetos", - "body": "En el host Windows, abra Group Policy → Computer Configuration → Windows Settings → Security Settings → Advanced Audit Policy Configuration → Object Access y habilite \"Audit File System\"." - }, - "configureFolderAuditing": { - "title": "2 · Configurar la auditoría de carpetas", - "body": "En cada carpeta que desee monitorear, abra Propiedades → Security → Advanced → Auditing y añada una entrada de auditoría para los principales y tipos de acceso que le interesen." - }, - "verifyEvents": { - "title": "3 · Verificar que los eventos aparecen en el log de Seguridad", - "body": "Abra Event Viewer y confirme que se generan eventos 4663/4670 cuando se accede a los objetos auditados." - }, - "activate": { - "title": "4 · Activar", - "body": "Active el módulo UTMStack para que los eventos de integridad de archivos comiencen a fluir." - } - } + "fields": { + "adversary_domain": "Dominio del adversario", + "adversary_geolocation_asn": "ASN del adversario", + "adversary_geolocation_aso": "ASO del adversario", + "adversary_geolocation_country": "País del adversario", + "adversary_host": "Host del adversario", + "adversary_ip": "IP del adversario", + "adversary_url": "URL del adversario", + "adversary_user": "Usuario del adversario", + "assignee": "Asignado a", + "category": "Categoría", + "dataSource": "Sensor", + "dataType": "Tipo de dato", + "description": "Descripción", + "id": "ID", + "impactScore": "Riesgo", + "impact_availability": "Disponibilidad", + "impact_confidentiality": "Confidencialidad", + "impact_integrity": "Integridad", + "incidentDetail_incidentName": "Nombre del incidente", + "incidentDetail_incidentId": "Id del incidente", + "isIncident": "Es incidente", + "name": "Nombre de la alerta", + "notes": "Notas", + "severity": "Severidad", + "status": "Estado", + "tags": "Etiquetas", + "target_domain": "Dominio del objetivo", + "target_geolocation_asn": "ASN del objetivo", + "target_geolocation_aso": "ASO del objetivo", + "target_geolocation_country": "País del objetivo", + "target_host": "Host del objetivo", + "target_ip": "IP del objetivo", + "target_url": "URL del objetivo", + "target_user": "Usuario del objetivo", + "technique": "Técnica" }, - "socAi": { - "sections": { - "overview": { - "title": "1 · Acerca de SOC AI", - "body": "SOC AI amplía UTMStack con un analista respaldado por LLM que resume alertas y sugiere los próximos pasos. Se ejecuta con el proveedor que configure." - }, - "chooseProvider": { - "title": "2 · Elegir un proveedor", - "body": "Seleccione un proveedor: OpenAI, Anthropic, Azure OpenAI, Google Gemini, Ollama, Mistral, DeepSeek, Groq o un endpoint personalizado compatible con OpenAI." - }, - "configureCredentials": { - "title": "3 · Configurar credenciales", - "body": "Proporcione la API key y (cuando corresponda) el nombre del modelo y la URL del endpoint." - }, - "activate": { - "title": "4 · Activar", - "body": "Active el módulo UTMStack para que SOC AI comience a trabajar con las alertas." - } - } + "tagFilter": { + "tags": "Etiquetas", + "tag_one": "{{count}} etiqueta", + "tag_other": "{{count}} etiquetas", + "clearSelection": "Limpiar selección", + "noTags": "Sin etiquetas" }, - "windowsFaa": { - "sections": { - "enableAuditPolicy": { - "title": "1 · Habilitar la auditoría de acceso a objetos", - "body": "En el host Windows, abra Group Policy → Computer Configuration → Windows Settings → Security Settings → Advanced Audit Policy Configuration → Object Access y habilite \"Audit File System\"." - }, - "configureFolderAuditing": { - "title": "2 · Configurar la auditoría de carpetas", - "body": "En cada carpeta que desee monitorear, abra Propiedades → Security → Advanced → Auditing y añada una entrada de auditoría para los principales y tipos de acceso que le interesen." - }, - "activate": { - "title": "3 · Activar", - "body": "Active el módulo UTMStack para que los eventos de actividad de archivos comiencen a fluir." - } - } + "bulk": { + "selected": "{{count}} seleccionadas", + "setStatus": "Cambiar estado", + "addTag": "Añadir etiqueta", + "noTags": "Sin etiquetas", + "addToIncident": "Añadir a incidente", + "clear": "Limpiar" }, - "awsBeanstalk": { - "sections": { - "openConsole": { - "title": "1 · Abrir la consola de Elastic Beanstalk", - "body": "En la consola de AWS, abra Elastic Beanstalk." - }, - "environment": { - "title": "2 · Abrir la página de administración del entorno", - "body": "Navegue a la página de administración del entorno que desea monitorear." - }, - "configuration": { - "title": "3 · Abrir Configuración", - "body": "Seleccione Configuration." - }, - "software": { - "title": "4 · Modificar la configuración de Software", - "body": "En la categoría Software configuration, seleccione Modify." - }, - "s3LogStorage": { - "title": "5 · Habilitar el almacenamiento de logs en S3", - "body": "En S3 log storage, seleccione Rotate logs para subir los logs rotados a Amazon S3." - }, - "cloudwatchStreaming": { - "title": "6 · Habilitar la transmisión de CloudWatch Logs", - "body": "En Instance log streaming to CloudWatch Logs, habilite la transmisión, establezca el período de retención y elija si desea subir los logs existentes." - }, - "activate": { - "title": "7 · Activar", - "body": "Active el módulo UTMStack para que los eventos de Beanstalk comiencen a fluir." - } - } + "tagEditor": { + "tag": "Etiqueta", + "noTagsYet": "Aún no hay etiquetas", + "createTag": "Crear etiqueta", + "newTagName": "Nombre de la etiqueta…", + "createApply": "Crear y aplicar etiqueta", + "save": "Guardar", + "cancel": "Cancelar", + "edit": "Editar etiqueta", + "delete": "Eliminar etiqueta", + "systemLocked": "Etiqueta del sistema (bloqueada)", + "alreadyExists": "Esa etiqueta ya existe.", + "color": "Color {{color}}", + "createRule": "Crear regla de etiquetado con esta etiqueta" }, - "awsFargate": { - "sections": { - "taskDefinition": { - "title": "1 · Actualizar la definición de tarea", - "body": "En la definición de tarea del Fargate, establezca el logDriver en \"awslogs\" y defina el nombre del grupo de logs." - }, - "cloudwatchLogs": { - "title": "2 · Confirmar que CloudWatch Logs está recibiendo logs", - "body": "Abra la consola de CloudWatch Logs y confirme que el grupo de logs se está llenando cuando se ejecutan las tareas." - }, - "iamPrerequisite": { - "title": "3 · Requisito previo del usuario IAM", - "body": "Esta integración comparte credenciales con el módulo AWS IAM User; asegúrese de que esté configurado con CloudWatchLogsReadOnlyAccess." - }, - "activate": { - "title": "4 · Activar", - "body": "Active el módulo UTMStack para que los eventos de Fargate comiencen a fluir." - } - } + "table": { + "actions": "Acciones", + "alert": "Alerta", + "status": "Estado", + "technique": "Técnica", + "severity": "Severidad", + "risk": "Riesgo", + "echoes": "Ecos", + "time": "Hora", + "riskHint": "Puntuación de riesgo (0–100), coloreada por severidad", + "source": "Origen", + "adversary": "Adversario" }, - "awsIamUser": { - "sections": { - "iamConsole": { - "title": "1 · Abrir la consola de IAM", - "body": "En la consola de AWS, vaya a IAM → Users → Add users." - }, - "createUser": { - "title": "2 · Crear el usuario", - "body": "Elija un nombre de usuario (por ejemplo, utmstack-ingest). Seleccione acceso programático." - }, - "programmaticAccess": { - "title": "3 · Establecer el tipo de credencial", - "body": "Seleccione \"Access key — Programmatic access\"." - }, - "attachPolicy": { - "title": "4 · Adjuntar la política de lectura de CloudWatch", - "body": "Adjunte la política administrada por AWS CloudWatchLogsReadOnlyAccess." - }, - "review": { - "title": "5 · Revisar el usuario", - "body": "Revise los detalles del usuario y haga clic en Create user." - }, - "copyKeys": { - "title": "6 · Copiar el ID de clave de acceso y el secreto", - "body": "Copie el Access key ID y la Secret access key; el secreto se muestra una sola vez." - }, - "createLogGroup": { - "title": "7 · Crear un grupo de logs en CloudWatch", - "body": "En CloudWatch → Log groups, crea un grupo de logs llamado \"utmstack\" — otras integraciones de AWS lo usarán como destino." - }, - "fillForm": { - "title": "8 · Completar el formulario", - "body": "Proporciona la clave de acceso, el secreto, la región predeterminada y el nombre del grupo de logs (p. ej. \"utmstack\") a UTMStack." - }, - "activate": { - "title": "9 · Activar", - "body": "Activa el módulo de UTMStack para que los eventos de AWS comiencen a fluir." - } - } + "row": { + "createRuleFromAlert": "Crear una etiqueta a partir de esta alerta", + "createIncident": "Crear incidente a partir de esta alerta", + "viewIncident": "Ver detalles del incidente", + "assignedTo": "Asignado a {{user}}", + "echoesTooltip": "{{count}} ecos — haz clic para expandir", + "echoesEmpty": "Sin ecos registrados" }, - "awsLambda": { - "sections": { - "iamPrerequisite": { - "title": "1 · Requisito previo: usuario IAM", - "body": "Lambda depende del módulo AWS IAM User — asegúrate de que esa integración esté configurada primero con CloudWatchLogsReadOnlyAccess." - }, - "cloudwatchStream": { - "title": "2 · Lambda ya transmite a CloudWatch Logs", - "body": "AWS Lambda publica automáticamente los logs de ejecución en CloudWatch Logs bajo /aws/lambda/. UTMStack los ingiere desde el grupo de logs que configuraste en la configuración del usuario IAM." - }, - "activate": { - "title": "3 · Activar", - "body": "Activa el módulo de UTMStack para que los eventos de Lambda comiencen a fluir." - } - } + "echoes": { + "title": "{{count}} ecos", + "close": "Cerrar", + "empty": "No hay ecos registrados para esta alerta.", + "loadError": "No se pudieron cargar los ecos." }, - "awsSqlServer": { - "sections": { - "openRds": { - "title": "1 · Abrir la consola de Amazon RDS", - "body": "Abre https://console.aws.amazon.com/rds/." - }, - "pickDb": { - "title": "2 · Seleccionar la instancia de BD", - "body": "En el panel de navegación, selecciona Databases y elige la instancia de BD que deseas supervisar." - }, - "modify": { - "title": "3 · Modificar la instancia", - "body": "Haz clic en Modify." - }, - "logExports": { - "title": "4 · Habilitar exportación de logs", - "body": "En la sección Log exports, selecciona Error log y Agent log para publicarlos en CloudWatch Logs." - }, - "apply": { - "title": "5 · Aplicar cambios", - "body": "Haz clic en Continue y luego en Modify DB Instance en la página de resumen." - }, - "activate": { - "title": "6 · Activar", - "body": "Activa el módulo de UTMStack para que los eventos de SQL Server comiencen a fluir." - } - } + "list": { + "loading": "Cargando alertas…", + "loadError": "No se pudieron cargar las alertas.", + "retry": "Reintentar", + "empty": "Ninguna alerta coincide con esta vista." }, - "awsPostgresql": { - "sections": { - "openRds": { - "title": "1 · Abrir la consola de Amazon RDS", - "body": "Abre https://console.aws.amazon.com/rds/." - }, - "pickDb": { - "title": "2 · Seleccionar la instancia de BD", - "body": "En el panel de navegación, selecciona Databases y elige la instancia de BD que deseas modificar." - }, - "logExports": { - "title": "3 · Habilitar exportación de logs", - "body": "En la sección Log exports, selecciona el log de PostgreSQL para publicarlo en CloudWatch Logs." - }, - "apply": { - "title": "4 · Aplicar cambios", - "body": "Haz clic en Continue y luego en Modify DB Instance en la página de resumen." - }, - "activate": { - "title": "5 · Activar", - "body": "Activa el módulo de UTMStack para que los eventos de PostgreSQL comiencen a fluir." + "badge": { + "incident": "Incidente", + "aiAssessed": "Evaluado por IA" + }, + "drawer": { + "setStatus": "Cambiar estado", + "completeFalsePositive": "Completar + falso positivo", + "addToIncident": "Añadir a incidente", + "partOfIncident": "Parte de un incidente", + "tabs": { + "summary": "Resumen", + "parties": "Partes", + "events": "Eventos", + "history": "Historial" + }, + "section": { + "description": "Descripción", + "solution": "Solución", + "references": "Referencias", + "details": "Detalles", + "yourNotes": "Tus notas", + "notes": "Notas" + }, + "details": { + "severity": "Severidad", + "risk": "Riesgo", + "category": "Categoría", + "technique": "Técnica", + "sensor": "Sensor", + "dataType": "Tipo de dato", + "alertId": "ID de alerta", + "statusNote": "Nota de estado", + "assignee": "Asignado a" + }, + "incidentDetail": { + "incident": "Incidente", + "id": "ID", + "createdBy": "Creado por", + "created": "Creado" + }, + "notesPlaceholder": "Añade notas de investigación…", + "saveNotes": "Guardar notas", + "assignee": "Asignar", + "assign": "Asignar", + "unassign": "Quitar asignación", + "unassigned": "Sin asignar", + "loadingUsers": "Cargando usuarios…", + "observationLabel": "Observación", + "observationPlaceholder": "Añade una observación…", + "cancel": "Cancelar", + "continue": "Continuar" + }, + "related": { + "sample": "Una muestra de hasta ~11 eventos que el motor almacenó en esta alerta. Usa «Ver todos los registros relacionados» para el conjunto completo y sin límite.", + "loadingEchoes": "Cargando los eventos de sus echoes…", + "sampleWithEchoes": "Los eventos guardados en esta alerta y en sus {{count}} echoes ({{read}} leídos). Usa «Ver todos los registros relacionados» para el conjunto completo y sin límite.", + "empty": "No hay eventos de muestra almacenados en esta alerta. Carga el conjunto correlacionado completo en el Explorador de registros.", + "viewAll": "Ver todos los registros relacionados" + }, + "party": { + "source": "Origen / objetivo", + "adversary": "Adversario", + "noData": "Sin datos.", + "ip": "IP", + "host": "Host", + "user": "Usuario", + "domain": "Dominio", + "country": "País" + }, + "history": { + "empty": "Sin historial registrado.", + "by": "por {{user}}", + "actions": { + "UPDATE_STATUS": "Estado actualizado", + "UPDATE_TAGS": "Etiquetas actualizadas", + "UPDATE_NOTES": "Notas actualizadas", + "UPDATE_SOLUTION": "Solución actualizada", + "MARK_AS_INCIDENT": "Marcada como incidente" + }, + "detail": { + "statusTo": "Estado → {{status}}", + "tags": "Etiquetas: {{tags}}", + "aiAdded": "Evaluación de IA añadida", + "observationAdded": "Observación añadida", + "notesUpdated": "Notas actualizadas" } - } }, - "awsTrafficMirror": { - "sections": { - "createTarget": { - "title": "1 · Crear un destino de duplicación de tráfico", - "body": "En la consola de VPC, crea un Traffic Mirror Target que apunte a la interfaz de red de la VM del agente UTMStack." - }, - "createFilter": { - "title": "2 · Crear un filtro de duplicación de tráfico", - "body": "Crea un Traffic Mirror Filter y agrega reglas de entrada/salida para los protocolos que deseas duplicar (p. ej. todo TCP, todo UDP)." - }, - "createSession": { - "title": "3 · Crear una sesión de duplicación de tráfico", - "body": "Crea una Traffic Mirror Session que empareje cada interfaz de red de origen con el destino y el filtro que creaste." - }, - "iamPrerequisite": { - "title": "4 · Requisito previo: usuario IAM", - "body": "Asegúrate de que el módulo AWS IAM User también esté configurado para que UTMStack pueda leer los logs de flujo de VPC si es necesario." - }, - "activate": { - "title": "5 · Activar", - "body": "Activa el módulo de UTMStack para que el tráfico duplicado comience a procesarse." + "ai": { + "title": "Evaluación de IA del SOC", + "risk": "riesgo {{risk}}", + "score": "{{score}}/100", + "generate": "Generar resumen con IA", + "hint": "SOC-AI investiga esta alerta y añade una evaluación.", + "generating": "Analizando la alerta… puede tardar un minuto.", + "ready": "Resumen de IA listo", + "failed": "No se pudo generar el resumen de IA", + "slow": "El resumen de IA está tardando más de lo esperado. Aparecerá en la alerta cuando esté listo." + }, + "incident": { + "titleAdd_one": "Añadir {{count}} alerta a un incidente", + "titleAdd_other": "Añadir {{count}} alertas a un incidente", + "new": "Nuevo incidente", + "existing": "Incidente existente", + "nameLabel": "Nombre del incidente", + "namePlaceholder": "p. ej. Sospecha de intrusión de Scattered Spider", + "descriptionLabel": "Descripción", + "descriptionPlaceholder": "Resumen opcional…", + "pickLabel": "Elige un incidente", + "loading": "Cargando…", + "selectPlaceholder": "Selecciona un incidente…", + "willLink_one": "Se vinculará {{count}} alerta.", + "willLink_other": "Se vincularán {{count}} alertas.", + "cancel": "Cancelar", + "create": "Crear incidente", + "add": "Añadir a incidente" + }, + "toast": { + "statusUpdated": "Estado actualizado", + "statusFailed": "No se pudo actualizar el estado", + "tagsUpdated": "Etiquetas actualizadas", + "tagsFailed": "No se pudieron actualizar las etiquetas", + "tagCreateFailed": "No se pudo crear la etiqueta", + "tagUpdated": "Etiqueta actualizada", + "tagUpdateFailed": "No se pudo actualizar la etiqueta", + "tagDeleted": "Etiqueta eliminada", + "tagDeleteFailed": "No se pudo eliminar la etiqueta", + "notesSaved": "Notas guardadas", + "notesFailed": "No se pudieron guardar las notas", + "exportFailed": "No se pudo exportar el CSV", + "noRelatedLogs": "No se encontraron registros relacionados con esta alerta", + "relatedLogsFailed": "No se pudieron cargar los registros relacionados", + "incidentCreated": "Incidente creado", + "alertsAdded": "Alertas añadidas al incidente", + "incidentFailed": "No se pudo guardar el incidente", + "assigned": "Alerta asignada", + "unassigned": "Alerta sin asignar", + "assignFailed": "No se pudo actualizar el asignado", + "newAlertsToast_title": "Nuevas alertas", + "newAlertsToast_count_one": "{{count}} nueva alerta", + "newAlertsToast_count_other": "{{count}} nuevas alertas", + "newAlertsToast_view": "Ver" + } + }, + "incidents": { + "title": "Incidentes", + "subtitle": "Agrupa, tría y resuelve alertas relacionadas como incidentes.", + "refresh": "Actualizar", + "count_one": "{{count}} incidente", + "count_other": "{{count}} incidentes", + "openNow": "abiertos ahora", + "empty": "No hay incidentes que coincidan.", + "loadError": "No se pudieron cargar los incidentes.", + "retry": "Reintentar", + "unassigned": "Sin asignar", + "unknownUser": "Desconocido", + "status": { + "open": "Abierto", + "in_review": "En revisión", + "completed": "Completado", + "merged": "Fusionado" + }, + "sev": { + "high": "Alta", + "medium": "Media", + "low": "Baja", + "unknown": "Sin calificar" + }, + "toolbar": { + "search": "Buscar incidentes…", + "create": "Crear incidente", + "allSeverities": "Todas las severidades", + "export": "Exportar CSV" + }, + "statusTabs": { + "all": "Todos" + }, + "filters": { + "add": "Añadir filtro", + "clearAll": "Limpiar todo", + "filterValues": "Filtrar valores…", + "loadingValues": "Cargando valores…", + "noValues": "No se encontraron valores.", + "pickValue": "Elige un valor para añadir el filtro.", + "empty": "(vacío)", + "cancel": "Cancelar", + "addBtn": "Añadir" + }, + "ops": { + "IS": "es" + }, + "layout": { + "table": "Tabla", + "board": "Tablero" + }, + "table": { + "name": "Incidente", + "status": "Estado", + "severity": "Severidad", + "assignee": "Asignado", + "alerts": "Alertas", + "created": "Creado" + }, + "drawer": { + "created": "Creado {{date}}", + "alertsCount": "{{count}} alertas", + "solutionPlaceholder": "Resolución / notas de remediación…", + "solutionHint": "Se guarda al pasar el incidente a Completado.", + "tabs": { + "overview": "Resumen", + "alerts": "Alertas", + "notes": "Notas", + "history": "Historial" + }, + "section": { + "description": "Descripción", + "solution": "Solución", + "details": "Detalles" + }, + "details": { + "id": "ID", + "status": "Estado", + "severity": "Severidad", + "assignee": "Asignado", + "created": "Creado", + "alerts": "Alertas vinculadas" } - } - }, - "deceptivebytes": { - "source": "Deceptive Bytes", - "step1": { - "title": "Habilitar el listener de Deceptive Bytes en el Collector", - "body": "En el host donde está instalado el Collector, ejecuta este comando para abrir el listener syslog de Deceptive Bytes:", - "note": "Para usar TCP en lugar de UDP, reemplaza udp por tcp en el comando anterior." - }, - "step2": { - "title": "Configurar Deceptive Bytes para reenviar logs", - "body": "En la consola de administración de Deceptive Bytes, configura el reenvío syslog para enviar eventos al host del Collector en el puerto {{port}} (UDP). Deceptive Bytes emite syslog en formato CEF, que el Collector ingiere como tipo de datos deceptive-bytes." - } - }, - "fortigate": { - "source": "Firewall FortiGate", - "step1": { - "title": "Habilitar el listener de FortiGate en el Collector", - "body": "En el host donde está instalado el Collector, ejecuta este comando para abrir el listener syslog de FortiGate:", - "note": "Para usar TCP en lugar de UDP, reemplaza udp por tcp en el comando anterior." - }, - "step2": { - "title": "Configurar FortiGate para reenviar logs", - "body": "En el FortiGate, apunta el syslog al host del Collector en el puerto {{port}}. Ejecuta lo siguiente desde el CLI de FortiOS (o usa Log & Report → Log Settings → Syslog en la interfaz gráfica):", - "note": "Reemplaza la dirección del servidor si el Collector se ejecuta en un host diferente. Para múltiples colectores syslog, usa syslogd2/syslogd3/syslogd4." - } - }, - "fortiweb": { - "source": "FortiWeb WAF", - "step1": { - "title": "Habilitar el listener de FortiWeb en el Collector", - "body": "En el host donde está instalado el Collector, ejecuta este comando para abrir el listener syslog de FortiWeb:", - "note": "Para usar TCP en lugar de UDP, reemplaza udp por tcp en el comando anterior." - }, - "step2": { - "title": "Configurar FortiWeb para reenviar logs", - "body": "En el FortiWeb, crea una política syslog que apunte al host del Collector en el puerto {{port}} y habilita el registro syslog. Ejecuta lo siguiente desde el CLI de FortiWeb (o usa Log & Report → Log Policy → Syslog Policy en la interfaz gráfica):", - "note": "Asegúrate de que los tipos de log relevantes (Attack, Event, Traffic) estén habilitados para enviarse a syslog en la configuración de Log & Report." - } - }, - "paloalto": { - "source": "Firewall Palo Alto", - "step1": { - "title": "Habilitar el listener de Palo Alto en el Collector", - "body": "En el host donde está instalado el Collector, ejecuta este comando para abrir el listener syslog de Palo Alto:", - "note": "Para usar TCP en lugar de UDP, reemplaza udp por tcp en el comando anterior." - }, - "step2": { - "title": "Crear un perfil de servidor Syslog", - "body": "En PAN-OS, ve a Device → Server Profiles → Syslog y agrega un perfil. Establece la dirección del servidor en {{host}}, transporte UDP, puerto {{port}} y formato BSD." - }, - "step3": { - "title": "Reenviar logs y confirmar", - "body": "Crea un perfil de Log Forwarding (Objects → Log Forwarding) que envíe los tipos de log Traffic, Threat y otros al perfil syslog anterior, asígnalo a las reglas de Security policy (Policies → Security → rule → Actions → Log Forwarding) y luego haz Commit." - } - }, - "pfsense": { - "source": "Firewall pfSense", - "step1": { - "title": "Habilitar el listener de pfSense en el Collector", - "body": "En el host donde está instalado el Collector, ejecuta este comando para abrir el listener syslog de pfSense:", - "note": "Para usar TCP en lugar de UDP, reemplaza udp por tcp en el comando anterior." - }, - "step2": { - "title": "Habilitar el registro remoto en pfSense", - "body": "En la interfaz web de pfSense, ve a Status → System Logs → Settings. En Remote Logging Options, marca Enable Remote Logging, establece un servidor de log remoto en {{host}}:{{port}}, elige qué logs enviar (o Everything) y haz clic en Save." - } - }, - "sonicwall": { - "source": "Firewall SonicWall", - "step1": { - "title": "Habilitar el listener de SonicWall en el Collector", - "body": "En el host donde está instalado el Collector, ejecuta este comando para abrir el listener syslog de SonicWall:", - "note": "Para usar TCP en lugar de UDP, reemplaza udp por tcp en el comando anterior." - }, - "step2": { - "title": "Agregar un servidor Syslog en SonicOS", - "body": "En SonicOS, ve a Device → Log → Syslog (Manage → Log → Syslog en firmware más antiguo) y agrega un Syslog Server con dirección {{host}} y puerto {{port}}. Establece el Syslog Format en ArcSight (CEF) — UTMStack analiza SonicWall en CEF — y haz clic en Apply." - } - }, - "sophosxg": { - "source": "Sophos Firewall", - "step1": { - "title": "Habilitar el listener de Sophos Firewall en el Collector", - "body": "En el host donde está instalado el Collector, ejecuta este comando para abrir el listener syslog de Sophos Firewall:", - "note": "Para usar TCP en lugar de UDP, reemplaza udp por tcp en el comando anterior." - }, - "step2": { - "title": "Agregar un servidor Syslog en Sophos Firewall", - "body": "En la consola de Sophos Firewall (SFOS), ve a System → System services → Log settings y agrega un Syslog Server con dirección {{host}} y puerto {{port}}. Elige los tipos de log que deseas reenviar (firewall, IPS, ATP, web, etc.) y haz clic en Apply." - } - }, - "suricata": { - "source": "Suricata IDS", - "step1": { - "title": "Habilitar el listener de Suricata en el Collector", - "body": "En el host donde está instalado el Collector, ejecuta este comando para abrir el listener de Suricata:", - "note": "Para usar TCP en lugar de UDP, reemplaza udp por tcp en el comando anterior." - }, - "step2": { - "title": "Enviar logs EVE de Suricata a syslog", - "body": "Suricata se ingiere como JSON (EVE). En el host de Suricata, edita suricata.yaml y configura la salida eve-log para escribir en syslog:", - "note": "Luego reinicia Suricata: sudo systemctl restart suricata" - }, - "step3": { - "title": "Reenviar syslog al Collector", - "body": "Apunta la facilidad local5 (donde Suricata escribe ahora) al Collector. Agrega esta regla en /etc/rsyslog.d/60-utmstack-suricata.conf en el host de Suricata:", - "note": "Usa @@ en lugar de @ para TCP. Luego reinicia rsyslog: sudo systemctl restart rsyslog" - } - }, - "o365_graph": { - "intro": { - "title": "Cómo funciona", - "body": "UTMStack se conecta a Microsoft 365 con una app registrada en Azure AD y consulta Microsoft Graph por eventos de seguridad: alertas, incidentes, auditoría de directorio, sign-ins, detecciones de riesgo, hunting queries y auditoría de Purview. No se instala ningún agente en el tenant.", - "diagram": { - "source": "eventos de seguridad", - "edge": "Microsoft Graph", - "utmstackSub": "correlación & alertas" - }, - "note": "UTMStack requiere solo acceso de lectura a la API de Graph — no se piden permisos de escritura." - }, - "appSection": "Registro de la app en Azure", - "steps": { - "azurePortal": { - "title": "Abrir Microsoft Entra ID", - "body": "Abrí el portal de Azure (portal.azure.com) y hacé clic en Microsoft Entra ID." - }, - "appRegistrations": { - "title": "Ir a App registrations", - "body": "En el menú izquierdo, hacé clic en App registrations." - }, - "registerApp": { - "title": "Registrar una app nueva", - "body": "Hacé clic en New registration. Nombrala UTMStack Graph Dev, elegí Accounts in this organizational directory only (Single-tenant) y hacé clic en Register." - }, - "clientSecret": { - "title": "Crear un client secret", - "body": "Andá a Certificates & Secrets → New client secret. Agregá una descripción, poné la expiración en 730 días (24 meses) y hacé clic en Add.", - "copyNote": "Copiá el valor del secret de inmediato — solo se muestra una vez y no se puede recuperar después." - }, - "apiPermissions": { - "title": "Agregar permisos de Microsoft Graph", - "body": "Andá a API Permissions → Add a permission y elegí Microsoft Graph, luego Application permissions." - }, - "graphPermissions": { - "title": "Agregar las cuatro permissions de Graph", - "body": "Agregá SecurityEvents.Read.All, Directory.Read.All, AuditLog.Read.All y IdentityRiskEvent.Read.All." - }, - "adminConsent": { - "title": "Dar admin consent", - "body": "De vuelta en API Permissions, hacé clic en Grant admin consent y confirmá." - }, - "noteIds": { - "title": "Copiar los IDs de la app", - "body": "Andá a Overview de la app y copiá el Application (client) ID y el Directory (tenant) ID. También necesitás el valor del secret que copiaste en el paso 4." - } - }, - "credentialsSection": "Credenciales", - "credentials": { - "title": "Conectar tu tenant de Microsoft 365", - "body": "Ingresá los datos de los pasos anteriores. UTMStack verifica las credenciales antes de guardar. Podés agregar varios grupos de configuración." - }, - "fields": { - "tenantId": { - "label": "Tenant ID (Directory ID)" - }, - "clientId": { - "label": "Client ID (Application ID)" - }, - "clientSecret": { - "label": "Client Secret" - }, - "cloudEnv": { - "label": "Cloud Environment (opcional)", - "hint": "Commercial (default), GCC, GCCHigh o DoD" - } - } - } - }, - "cloud": { - "howItWorksTitle": "Cómo funciona", - "howItWorksBody": "{{name}} se ejecuta completamente dentro de UTMStack — no hay agente ni colector que desplegar. Proporciona credenciales de API de solo lectura y UTMStack extraerá eventos en un horario, los analizará y los ingerirá en Log Explorer.", - "connectionTitle": "Conexión", - "noFields": "No hay campos de conexión configurados.", - "testConnection": "Probar conexión", - "save": "Guardar", - "afterTitle": "Qué verás después de conectar", - "after1": "UTMStack realiza un relleno inicial de eventos recientes.", - "after2": "Desde entonces, los eventos se extraen cada 1–5 minutos (depende de la API).", - "after3": "La integración aparece bajo Fuentes de datos con el estado actual de extracción y retraso.", - "tenants": { - "title": "Grupos de configuración configurados", - "empty": "Aún no hay grupos de configuración. Añade el primero más abajo.", - "loading": "Cargando grupos de configuración…", - "nameLabel": "Nombre del grupo de configuración", - "namePlaceholder": "p. ej. acme-prod", - "add": "Añadir grupo de configuración", - "update": "Actualizar grupo de configuración", - "delete": "Eliminar", - "edit": "Editar", - "cancel": "Cancelar", - "editing": "Editando: {{name}}", - "selectFile": "Seleccionar archivo", - "replaceFile": "Reemplazar archivo", - "fileLoaded": "Archivo cargado", - "invalidJson": "No se pudo procesar el archivo como JSON.", - "createError": "No se pudo crear el grupo de configuración. Inténtalo de nuevo.", - "updateError": "No se pudo actualizar el grupo de configuración. Inténtalo de nuevo.", - "createSuccess": "Grupo de configuración creado correctamente.", - "updateSuccess": "Grupo de configuración actualizado correctamente." - }, - "google": { - "sections": { - "createTopic": { - "title": "1 · Crea un tema de Pub/Sub", - "body": "En la consola de Google Cloud, abre Pub/Sub → Temas y crea un nuevo tema. UTMStack recibirá eventos a través de este tema.", - "docLabel": "Abrir la página de topics de Pub/Sub" - }, - "createSubscription": { - "title": "2 · Crea una suscripción", - "body": "Dentro del tema, crea una suscripción de tipo Pull. UTMStack obtendrá los mensajes desde esta suscripción." - }, - "configureSubscription": { - "title": "3 · Configura la suscripción", - "body": "Establece la duración de retención de mensajes según tu tolerancia a interrupciones (7 días por defecto está bien). Deja el plazo de confirmación en 10 segundos y la expiración en «Nunca expirar»." - }, - "logsRouter": { - "title": "4 · Abre Logs Router", - "body": "Navega a Logging → Logs Router y crea un nuevo sink. Esto reenvía los logs del proyecto al tema de Pub/Sub creado arriba." - }, - "sinkDestination": { - "title": "5 · Apunta el sink al tema", - "body": "Elige Tema de Cloud Pub/Sub como destino del sink y selecciona el tema que creaste. Usa filtros de inclusión/exclusión para acotar lo que se reenvía." - }, - "serviceAccount": { - "title": "6 · Crea una cuenta de servicio", - "body": "Abre IAM y administración → Cuentas de servicio y crea una nueva cuenta de servicio. Asígnale el rol Editor de Pub/Sub para que UTMStack pueda leer desde la suscripción.", - "docLabel": "Abrir la página de cuentas de servicio" - }, - "serviceAccountKey": { - "title": "7 · Genera una clave para la cuenta de servicio", - "body": "Abre la cuenta de servicio, ve a la pestaña Claves y añade una nueva clave. Selecciona JSON como tipo de clave." - }, - "downloadKey": { - "title": "8 · Descarga y carga la clave JSON", - "body": "Guarda el archivo JSON que Google descarga: su contenido va en el campo «Clave JSON de cuenta de servicio» a continuación." - } - }, - "fields": { - "projectId": { - "label": "ID del proyecto" - }, - "subscription": { - "label": "Nombre de la suscripción" - }, - "jsonKey": { - "label": "Clave JSON de cuenta de servicio" - } - }, - "intro": { - "title": "Cómo funciona", - "body": "UTMStack lee la actividad de auditoría directamente desde Google Cloud a través de Pub/Sub. Un sink de Logs Router transmite los registros de tu proyecto a un topic de Pub/Sub; UTMStack ejecuta un puller interno que lee una suscripción Pull de ese topic mediante una clave de cuenta de servicio. No se instala nada en tu proyecto de GCP.", - "diagram": { - "source": "Cloud Logging", - "edge1": "Logs Router", - "pubsub": "Pub/Sub", - "pubsubSub": "topic + suscripción", - "edge2": "extrae", - "utmstackSub": "alertas y correlación" - }, - "note": "Ningún agente se ejecuta en GCP — UTMStack extrae mensajes de la suscripción de Pub/Sub usando la clave JSON de cuenta de servicio que proporcionas a continuación." - }, - "credentials": { - "title": "Configuración de Pub/Sub", - "body": "Usa los valores obtenidos anteriormente para configurar UTMStack. Puedes monitorear más de un proyecto guardando configuraciones adicionales.", - "mapping": { - "intro": "Referencia de campos", - "projectId": "Project ID — el proyecto de GCP que contiene tu topic, suscripción y sink", - "subscription": "Nombre de suscripción — la suscripción Pull creada en el paso 2", - "jsonKey": "Clave JSON de cuenta de servicio — el archivo descargado en el paso 8" - } - } }, - "azure": { - "sections": { - "sharedAccessPolicy": { - "title": "2 · Añade una directiva de acceso compartido", - "body": "Abre el Event Hub → Directivas de acceso compartido y crea una nueva directiva con el permiso Listen únicamente." - }, - "connectionString": { - "title": "3 · Copia la cadena de conexión principal", - "body": "Abre la directiva y copia la cadena de conexión principal. Tiene este aspecto: Endpoint=sb://...;SharedAccessKeyName=...;SharedAccessKey=..." - }, - "consumerGroup": { - "title": "4 · Crea un consumer group dedicado", - "body": "Abre el Event Hub → Consumer groups y crea uno nuevo para UTMStack. No reutilices $Default; dale a UTMStack su propio grupo para que los checkpoints no choquen con otros consumidores.", - "warn": "Crea un consumer group específicamente para UTMStack. No uses $Default ni ningún otro grupo que ya esté en uso — reutilizar un consumer group entre consumidores no relacionados puede provocar comportamientos inesperados y pérdida de eventos. Todas las instancias de UTMStack deben compartir el mismo consumer group para procesar los eventos en conjunto." - }, - "storageContainer": { - "title": "6 · Crea un contenedor dentro de la cuenta de almacenamiento", - "body": "Dentro de la cuenta de almacenamiento → Contenedores, crea uno nuevo. Anota el nombre del contenedor y la cadena de conexión de la cuenta (Claves de acceso → Cadena de conexión)." - }, - "eventGrid": { - "title": "7 · Registra el proveedor de recursos Event Grid", - "body": "En Suscripciones → Proveedores de recursos, registra Microsoft.EventGrid si aún no está. Esto permite que Azure reenvíe eventos de suscripción a tu Event Hub." - }, - "createEventHub": { - "title": "Crear un Event Hub", - "body": "En el Azure Portal, crea un namespace de Event Hubs y un Event Hub dentro de él. UTMStack leerá los eventos de este hub.", - "docLabel": "Inicio rápido: Crear un event hub usando el Azure portal" - }, - "createStorageAccount": { - "title": "Crear una Storage Account", - "body": "UTMStack necesita una Storage Account para registrar su posición de lectura. Crea una en la misma región que el Event Hub.", - "docLabel": "Inicio rápido: Crear una storage account" - }, - "storageConnection": { - "title": "Copiar la cadena de conexión de la Storage Account", - "body": "Obtén la cadena de conexión de la Storage Account con clave en: All services → Storage accounts → tu cuenta → Access keys. UTMStack la usa para almacenar los checkpoints del Event Hub." - }, - "createEventSubscription": { - "title": "Crear una Event Subscription", - "body": "En el panel Events de la suscripción, crea un nuevo evento haciendo clic en Events → Event Subscription." - }, - "configureEventSubscription": { - "title": "Apuntar la Event Subscription a tu Event Hub", - "body": "Configura la Event Subscription para enviar registros al Event Hub creado en el paso 1." - } - }, - "fields": { - "eventHubConnection": { - "label": "Cadena de conexión del Event Hub" - }, - "consumerGroup": { - "label": "Consumer group" - }, - "storageContainer": { - "label": "Nombre del contenedor de almacenamiento" - }, - "storageConnection": { - "label": "Cadena de conexión de la cuenta de almacenamiento" - } - }, - "intro": { - "title": "Cómo funciona", - "body": "UTMStack lee la actividad de auditoría directamente desde un Azure Event Hub. Configuras tu suscripción de Azure para transmitir eventos a un Event Hub; UTMStack ejecuta un puller interno que lee ese hub y registra su progreso en una Storage Account. No se instala nada en tu tenant de Azure.", - "diagram": { - "source": "eventos de suscripción", - "edge1": "transmite a", - "eventHub": "Event Hub", - "eventHubSub": "flujo de eventos", - "edge2": "extrae", - "utmstackSub": "alertas y correlación" - }, - "note": "Ningún agente se ejecuta en Azure — UTMStack extrae eventos del Event Hub usando las cadenas de conexión que proporcionas a continuación." - }, - "sampleLabel": "Cadena de conexión de ejemplo:", - "credentials": { - "title": "Configuración de Event Hub", - "body": "Usa los datos obtenidos en los pasos anteriores para configurar UTMStack. Puedes agregar más de un Event Hub guardando configuraciones adicionales.", - "mapping": { - "intro": "Referencia de campos", - "eventHubConnection": "Cadena de conexión de Event Hub — valor obtenido en el paso 3", - "consumerGroup": "Consumer group — valor obtenido en el paso 4", - "storageContainer": "Nombre del storage container — valor obtenido en el paso 6", - "storageConnection": "Cadena de conexión de storage account — valor obtenido en el paso 7" - } - } - }, - "aws": { - "intro": { - "title": "Cómo funciona", - "body": "UTMStack lee la actividad de auditoría directamente desde AWS CloudWatch Logs. CloudTrail captura llamadas a la API y eventos de gestión en tu cuenta de AWS, los reenvía a un log group de CloudWatch, y UTMStack consulta ese grupo para ingestar y correlacionar eventos.", - "diagram": { - "source": "eventos API", - "edge1": "CloudTrail", - "cloudwatchSub": "log groups", - "edge2": "consulta", - "utmstackSub": "alertas y correlación" - }, - "note": "No se instala nada en AWS — UTMStack extrae los eventos de log usando credenciales IAM de solo lectura que tú proporcionas." - }, - "iamSection": "Configurar usuario IAM", - "iam": { - "dashboard": { - "title": "Abrir el panel IAM", - "body": "Abre la consola de AWS, navega al panel IAM y selecciona Users." - }, - "addUser": { - "title": "Agregar un usuario", - "body": "Haz clic en Add user, introduce un nombre descriptivo y continúa al siguiente paso." - }, - "attachPolicy": { - "title": "Adjuntar la política de solo lectura", - "body": "En Permissions, adjunta la política requerida. Selecciona CloudWatchLogsReadOnlyAccess para acceso de solo lectura a CloudWatch." - }, - "createUser": { - "title": "Crear el usuario", - "body": "Revisa la configuración y haz clic en Create user para aprovisionar la cuenta." - }, - "openUser": { - "title": "Abrir el nuevo usuario", - "body": "Abre el usuario recién creado haciendo clic en su nombre para ver sus detalles y gestionar credenciales." - }, - "securityTab": { - "title": "Ir a Security credentials", - "body": "Selecciona la pestaña Security credentials para crear las claves de acceso programático." - }, - "createKey": { - "title": "Crear una clave de acceso", - "body": "Haz clic en Create access key y elige la opción para una aplicación que se ejecuta fuera de AWS (acceso programático)." - }, - "confirmKey": { - "title": "Confirmar la creación", - "body": "Confirma la creación de la clave de acceso. AWS generará un Access Key ID y un Secret Access Key." - }, - "downloadKey": { - "title": "Guardar las credenciales", - "body": "Descarga el archivo de credenciales o copia el Access Key ID y el Secret Access Key en un lugar seguro — el Secret Access Key solo se muestra una vez." - } - }, - "credentials": { - "title": "Introducir credenciales", - "body": "Pega el Access Key ID y el Secret Access Key obtenidos en los pasos anteriores. UTMStack verifica las credenciales contra AWS antes de guardarlas." - }, - "cloudwatchSection": "Configurar AWS CloudWatch", - "cloudwatch": { - "createGroup": { - "title": "Crear un CloudWatch Log Group", - "body": "Abre la consola de CloudWatch, elige Log management y haz clic en Create log group." - }, - "nameGroup": { - "title": "Nombrar el log group y configurar la retención", - "body": "Introduce el nombre utmstack para el log group y establece la retención en 1 día. Haz clic en Create log group." - }, - "openTrail": { - "title": "Abrir CloudTrail y crear un trail", - "body": "En la consola de CloudTrail, haz clic en Create trail para comenzar a configurar un nuevo trail." - }, - "configureTrail": { - "title": "Configurar entrega, validación e integración con CloudWatch", - "body": "En el formulario de creación del trail, establece las siguientes opciones:", - "items": [ - "Nombre y alcance del trail: introduce un nombre descriptivo; activa Apply trail to all accounts in my organization si necesitas recolección a nivel de organización.", - "Destino S3: elige Create new S3 bucket (o selecciona uno existente) para la entrega de logs sin procesar.", - "Cifrado: habilita Log file SSE-KMS y selecciona la clave KMS adecuada.", - "Validación de archivos de log: activa para garantizar la integridad de los logs entregados (recomendado).", - "CloudWatch Logs: habilita la entrega a CloudWatch, selecciona Use existing log group e introduce el nombre exacto utmstack.", - "Rol IAM: proporciona o crea el rol que CloudTrail usará para escribir en S3 y publicar en CloudWatch." - ] - }, - "eventTypes": { - "title": "Seleccionar tipos de eventos", - "body": "Habilita las categorías de eventos necesarias para la monitorización y auditoría.", - "management": { - "label": "1 · Eventos de gestión", - "body": "Habilita Management events y selecciona All para registrar toda la actividad de API que gestiona recursos de AWS (crear, actualizar, eliminar)." - }, - "data": { - "label": "2 · Eventos de datos", - "body": "Agrega un Data event. Elige S3 y selecciona Log all events para capturar operaciones a nivel de objeto como GetObject y PutObject." - }, - "network": { - "label": "3 · Eventos de actividad de red", - "body": "En la sección Network Activities agrega al menos un servicio (p. ej. ec2.amazonaws.com) y habilita Log all events." - } - }, - "review": { - "title": "Revisar y crear el trail", - "body": "En la pantalla Configure event aggregation acepta los valores predeterminados (o ajústalos si es necesario). Revisa todos los ajustes y haz clic en Create trail." - } - }, - "fields": { - "accessKeyId": { - "label": "ID de clave de acceso de AWS" - }, - "secretAccessKey": { - "label": "Clave de acceso secreta de AWS" - }, - "region": { - "label": "Región predeterminada de AWS" - }, - "logGroupName": { - "label": "Nombre del log group" - } - } - }, - "crowdstrike": { - "intro": { - "title": "Cómo funciona", - "body": "UTMStack lee detecciones y actividad de auditoría directamente desde la API de Event Streams de CrowdStrike Falcon. Creas un cliente API en Falcon con alcance de Event Streams; UTMStack ejecuta un puller interno que transmite eventos usando esas credenciales. No se instala nada en tus endpoints ni en Falcon.", - "diagram": { - "source": "detecciones y eventos", - "edge1": "Event Streams API", - "api": "Falcon API", - "apiSub": "flujo de eventos", - "edge2": "extrae", - "utmstackSub": "alertas y correlación" - }, - "note": "UTMStack no despliega ningún agente — extrae eventos de Falcon usando las credenciales de cliente API de solo lectura que proporcionas a continuación." - }, - "sections": { - "apiClients": { - "title": "Abrir API Clients and Keys", - "body": "En la consola de Falcon, abre el menú (ícono de hamburguesa, arriba a la izquierda) y ve a Support and resources → API Clients and Keys." - }, - "createClient": { - "title": "Crear un nuevo cliente API", - "body": "Haz clic en Create API Client para iniciar una nueva definición de cliente." - }, - "scopes": { - "title": "Nombrar el cliente y otorgar alcance de Event Streams", - "body": "Asigna al cliente un nombre descriptivo (UTMStack lo usa para identificar la fuente de eventos) y selecciona los alcances de API requeridos para Event Streams. Haz clic en Create para generar las credenciales." - }, - "recordCredentials": { - "title": "Registrar las credenciales", - "body": "Copia el Client ID, el Client Secret y la Base URL para tu región de CrowdStrike. El secreto se muestra solo una vez — guárdalo de forma segura. Pegarás los tres en el formulario a continuación." - } - }, - "credentials": { - "title": "Configuración de cliente API", - "body": "Usa las credenciales de los pasos anteriores para configurar UTMStack. Puedes agregar más de un cliente de CrowdStrike guardando configuraciones adicionales.", - "mapping": { - "intro": "Referencia de campos", - "appName": "Nombre de la app — el nombre descriptivo del cliente del paso 3 (identifica la fuente de eventos)", - "clientId": "Client ID — valor registrado en el paso 4", - "clientSecret": "Client Secret — valor registrado en el paso 4 (se muestra solo una vez)", - "cloudRegionUrl": "Base URL — el endpoint de tu región, p. ej. https://api.crowdstrike.com (us-1), https://api.us-2.crowdstrike.com (us-2), https://api.eu-1.crowdstrike.com (eu-1)" - } - }, - "fields": { - "appName": { - "label": "Nombre de la app" - }, - "clientId": { - "label": "Client ID" - }, - "clientSecret": { - "label": "Client Secret" - }, - "cloudRegionUrl": { - "label": "Base URL (región de nube)" + "alerts": { + "empty": "No hay alertas vinculadas a este incidente.", + "remove": "Desvincular alerta", + "removeConfirm": "¿Desvincular «{{name}}» de este incidente?", + "removed": "Alerta desvinculada", + "removeError": "No se pudo desvincular la alerta", + "loadingAlert": "Cargando alerta…", + "alertGone": "Esta alerta ya no está en el almacén — puede que la retención la haya eliminado.", + "alertFailed": "No se pudo cargar la alerta.", + "openInAlerts": "Abrir en Alertas" + }, + "notes": { + "empty": "Aún no hay notas.", + "add": "Agregar nota", + "addError": "No se pudo agregar la nota", + "placeholder": "Escribe una nota…" + }, + "history": { + "empty": "Aún no hay historial." + }, + "toast": { + "statusChanged": "Estado del incidente actualizado", + "statusError": "No se pudo cambiar el estado", + "exportFailed": "No se pudo exportar el CSV" + }, + "assign": { + "assign": "Asignar", + "search": "Buscar usuarios…", + "unassign": "Quitar asignación", + "noUsers": "Sin usuarios", + "assigned": "Asignado a {{user}}", + "unassigned": "Incidente sin asignar", + "error": "No se pudo cambiar el asignado", + "custom": "Asignar personalizado", + "customPlaceholder": "Escribe un usuario…" + }, + "action": { + "INCIDENT_CREATED": "Incidente creado", + "INCIDENT_ALERT_ADD": "Alertas añadidas", + "INCIDENT_ALERT_STATUS_CHANGED": "Estado de alertas cambiado", + "INCIDENT_STATUS_CHANGE": "Estado cambiado", + "INCIDENT_NOTE_ADD": "Nota añadida", + "INCIDENT_NOTE_CHANGE": "Nota editada", + "INCIDENT_ASSIGNED": "Asignación cambiada" + }, + "create": { + "title": "Crear incidente", + "stepIndicator": "Paso {{current}} de {{total}}", + "selectedCount": "{{count}} alertas seleccionadas", + "submit": "Crear", + "success": "Incidente creado", + "error": "No se pudo crear el incidente", + "details": { + "nameLabel": "Nombre", + "namePlaceholder": "Título corto y descriptivo", + "descriptionLabel": "Descripción", + "descriptionPlaceholder": "Contexto, alcance, notas iniciales…" } - } } - }, - "custom": { - "whenTitle": "Cuándo usar esto", - "whenBody": "Cuando tu fuente no está en el catálogo. Reenvía syslog o JSON arbitrario a UTMStack y define un analizador para normalizar campos.", - "endpointsTitle": "Puntos finales", - "syslogUdp": "Syslog (UDP)", - "syslogTls": "Syslog (TLS)", - "httpJson": "HTTP / JSON", - "payloadTitle": "Ejemplo de payload JSON", - "parserTitle": "Define el analizador", - "parserBody": "Los eventos entrantes se almacenan bajo el tipo de dato {{dataType}}. Añade un filtro de parseo para él de modo que el payload sin procesar se mapee a campos estructurados, y luego crea reglas de alerta encima.", - "openEditor": "Abrir editor de analizador", - "powershellLabel": "PowerShell (Ejecutar como administrador)", - "linuxLabel": "Linux — bash", - "macosLabel": "macOS — bash", - "exampleLabel": "Ejemplo de destino syslog en {{name}}:", - "intro": { - "title": "Cómo funciona", - "body": "Una integración personalizada ingiere registros de cualquier fuente que los módulos integrados no cubren. Instala el UTMStack Collector, registra un listener para tus datos con el protocolo de tu elección y apunta tu fuente hacia él.", - "note": "Elige a continuación el protocolo que puede enviar tu fuente (syslog UDP/TCP/TLS, o HTTP/HTTPS para JSON) — el Collector crea el tipo de datos automáticamente." - }, - "diagram": { - "source": "Tu fuente", - "sourceSub": "cualquier app o dispositivo", - "forwarder": "Collector", - "ingests": "ingiere", - "utmstackSub": "alertas y correlación" - }, - "choose": { - "title": "Elegir protocolo y puerto", - "body": "Selecciona cómo envía datos tu fuente y el puerto en el que debe escuchar el Collector, luego ejecuta el comando de activación en el host del Collector.", - "portLabel": "Puerto de escucha", - "tlsFirst": "Primero carga tu certificado y clave TLS en el Collector:", - "enableLabel": "Luego habilita la integración:", - "authNote": "Para requerir autenticación, agrega --auth bearer (token) o --auth hmac — el Collector imprime un token para usar en el encabezado Authorization." - }, - "send": { - "title": "Apuntar tu fuente al Collector", - "bodyNetwork": "Configura tu fuente para enviar syslog {{proto}} a {{host}}:{{port}}. La mayoría de los dispositivos tienen una opción de syslog remoto o reenvío de registros para esto.", - "bodyHttp": "Envía tus eventos como JSON mediante HTTP POST a {{endpoint}}. El cuerpo de cada solicitud es un evento JSON:", - "httpBindNote": "El listener HTTP/HTTPS se enlaza a 127.0.0.1 (el host del Collector) de forma predeterminada, así que envía desde una app que se ejecute en ese host — o usa un reverse proxy como intermediario. Para fuentes remotas, usa syslog (UDP/TCP/TLS)." - }, - "manualCommand": { - "title": "Optional — Enable via the command line instead", - "intro": "Prefer the terminal? SSH into the Collector host and run the command below — it matches whatever protocol and port you have selected above." - } - }, - "remoteEnable": { - "title": "Habilitar esta integración remotamente", - "body": "Elige un Collector, selecciona el protocolo y puerto, luego habilita la integración — sin necesidad de SSH.", - "noPermission": "No tienes permiso para gestionar integraciones remotas. Pide a un administrador que otorgue el permiso integrations.write.", - "loadingCollectors": "Cargando Collectors…", - "noCollectors": "Aún no hay Collector registrado. Instala uno arriba para habilitar integraciones remotamente.", - "forwarderOffline": "Este Collector está sin conexión y no puede recibir cambios de configuración en este momento.", - "legendOnline": "{{count}} en línea", - "legendOffline": "{{count}} sin conexión", - "legendTotal": "{{count}} total", - "forwarderLabel": "Collector", - "protoLabel": "Protocolo", - "portLabel": "Puerto", - "currentStateLoading": "Comprobando configuración actual…", - "currentlyEnabled": "Actual: habilitado · {{proto}} · puerto {{port}}", - "currentlyDisabled": "Actual: deshabilitado · {{proto}} · puerto {{port}}", - "authLabel": "Autenticación", - "authNone": "Ninguno", - "authBearer": "Token portador", - "authHmac": "Firma HMAC", - "pathLabel": "Ruta", - "signatureHeaderLabel": "Encabezado de firma", - "certTitle": "Certificado TLS", - "certLoading": "Comprobando estado del certificado…", - "certLoaded": "Un certificado válido ya está cargado en este Collector.", - "certMissing": "No hay certificado cargado aún — carga uno para habilitar este protocolo.", - "certInvalid": "El certificado cargado no es válido: {{error}}", - "certPemLabel": "Certificado", - "keyPemLabel": "Clave privada", - "caPemLabel": "Certificado CA", - "uploadCertsButton": "Cargar certificado", - "certUploadSuccess": "Certificado cargado.", - "certUploadError": "No se pudo cargar el certificado.", - "certReadError": "No se pudieron leer los archivos seleccionados.", - "enableButton": "Habilitar integración", - "disableButton": "Deshabilitar integración", - "enableSuccess": "Integración habilitada.", - "disableSuccess": "Integración deshabilitada.", - "enableError": "No se pudo actualizar la integración.", - "secretWarning": "Almacena este token de forma segura — no se mostrará nuevamente.", - "sendToInstance": "Enviar a la instancia", - "enterpriseFeature": "Esta es una función Enterprise.", - "addCollector": "Añadir Collector", - "addApiKey": "Añadir clave API", - "apiKeyLabel": "Clave API", - "apiKeyHint": "Primero necesitarás una clave API.", - "apiKeyPlaceholder": "Selecciona una clave API", - "apiKeyAddNew": "Añadir clave API…", - "apiKeyNone": "Todavía no hay claves API", - "forwarderNoRemoteControl": "Este forwarder se instaló con el control remoto deshabilitado. Ignora la configuración enviada desde aquí, y eso solo se cambia en la propia máquina." - } - }, - "codeBlock": { - "copy": "Copiar", - "copied": "Copiado" - }, - "createDrawer": { - "title": "Nueva integración personalizada", - "moduleName": "Nombre del módulo", - "moduleNameHint": "Identificador único. Sin espacios.", - "moduleNamePlaceholder": "mi-app-personalizada", - "prettyName": "Nombre para mostrar", - "prettyNamePlaceholder": "Mi App Personalizada", - "dataType": "Tipo de datos", - "dataTypePlaceholder": "Identificador único para este tipo de datos", - "icon": "Icono", - "iconHint": "PNG, SVG, JPEG, GIF o WEBP. Máximo 3MB. Se usa como logo de la integración.", - "iconPreview": "Vista previa del icono", - "dataTypeExists": "Este tipo de datos ya existe", - "invalidFileType": "El icono debe ser un archivo de imagen válido (PNG, JPEG, SVG, GIF, WEBP)", - "fileTooLarge": "El icono no debe exceder 3MB", - "fileReadError": "Error al leer el archivo", - "cancel": "Cancelar", - "create": "Crear integración", - "creating": "Creando…", - "editTitle": "Editar integración", - "save": "Guardar", - "saving": "Guardando…", - "currentIcon": "Ícono actual — sube un archivo para reemplazarlo", - "name": "Nombre de la integración", - "namePlaceholder": "p. ej. Acme Firewall", - "description": "Descripción", - "descriptionPlaceholder": "Qué ingiere esta integración y por qué (opcional)", - "identifierHint": "Se almacena como “{{id}}” (derivado del nombre)", - "nameTaken": "Ese nombre de integración no está disponible — ya existe una integración con ese identificador.", - "removeIcon": "Eliminar icono", - "defaultIconNote": "Icono predeterminado — sube un archivo para usar el tuyo." - }, - "toast": { - "created": "Integración creada", - "updated": "Integración actualizada", - "updateError": "Error al actualizar la integración" - }, - "delete": { - "title": "Eliminar integración", - "confirm": "¿Eliminar esta integración?", - "yes": "Eliminar", - "no": "Cancelar", - "deleted": "Integración eliminada", - "error": "No se pudo eliminar la integración" - }, - "modules": { - "WINDOWS_AGENT": "Recopila actividad del sistema Windows, seguridad y registros de eventos a través del agente ligero de UTMStack instalado en cada host.", - "LINUX_AGENT": "Recopila registros del sistema Linux, autenticación y auditoría a través del agente ligero de UTMStack instalado en cada host.", - "MACOS": "Recopila actividad de registros del sistema y seguridad de macOS desde endpoints Apple Mac a través del agente ligero de UTMStack.", - "VMWARE": "Ingesta el syslog del hipervisor VMware ESXi para monitorear la actividad y eventos del host de virtualización en UTMStack.", - "NETFLOW": "Ingesta registros NetFlow de routers y switches para monitorear patrones de tráfico de red y detectar anomalías.", - "AWS_IAM_USER": "Ingesta actividad de cuentas AWS y llamadas a API mediante CloudTrail y CloudWatch para auditar el uso, acceso y cambios en la nube.", - "AZURE": "Ingesta registros de plataforma y actividad de Microsoft Azure para monitorear cargas de trabajo en la nube, identidad y cambios en recursos.", - "O365": "Ingesta registros de auditoría de Microsoft 365 en Exchange, Teams, SharePoint y OneDrive para monitorear la actividad de usuarios y administradores.", - "O365_GRAPH": "Ingesta eventos de seguridad de Microsoft Graph: alertas, incidentes, auditoría del directorio, inicios de sesión, detecciones de riesgo y logs de auditoría de Purview para monitorear identidad y actividad de amenazas en tu tenant.", - "GCP": "Ingesta registros de auditoría y actividad de Google Cloud Platform para monitorear cómputo, almacenamiento e identidad en los proyectos.", - "KASPERSKY": "Ingesta detecciones de Kaspersky Security Center y telemetría de endpoints para correlacionar actividad de malware en la red.", - "ESET": "Ingesta detecciones y telemetría de endpoints de ESET PROTECT para correlacionar la defensa multicapa contra malware en tu infraestructura.", - "BITDEFENDER": "Ingesta detecciones de Bitdefender GravityZone y telemetría de endpoints para correlacionar amenazas en los dispositivos empresariales.", - "SENTINEL_ONE": "Ingesta detecciones de endpoints y telemetría de comportamiento de SentinelOne para correlacionar e investigar amenazas a escala.", - "SOPHOS": "Ingesta detecciones de Sophos Central en endpoints, servidores, firewall y correo electrónico para correlacionar amenazas en un solo lugar.", - "CROWDSTRIKE": "Ingesta detecciones de endpoints y cargas de trabajo de CrowdStrike Falcon para correlacionar actividad de amenazas nativas de la nube en UTMStack.", - "CISCO": "Ingesta registros de tráfico, VPN y amenazas del firewall Cisco ASA para monitorear la seguridad perimetral y el acceso en UTMStack.", - "MERAKI": "Ingesta el syslog del firewall y dispositivos de seguridad Cisco Meraki para monitorear el tráfico de red gestionado en la nube y las amenazas.", - "FIRE_POWER": "Ingesta registros de Cisco Firepower NGFW e IPS para monitorear intentos de intrusión y actividad de amenazas en el perímetro.", - "CISCO_SWITCH": "Ingesta el syslog y la telemetría de switches Cisco para monitorear el rendimiento de la red, cambios de configuración y seguridad.", - "FORTIGATE": "Ingesta registros de tráfico y amenazas de Fortinet FortiGate NGFW para monitorear la seguridad perimetral y la actividad de red.", - "FORTIWEB": "Ingesta registros WAF de Fortinet FortiWeb para monitorear ataques a aplicaciones web y proteger los servicios y APIs expuestos.", - "SOPHOS_XG": "Ingesta registros del firewall Sophos XG con filtrado web, IPS y VPN para monitorear el tráfico de red y las amenazas.", - "PALO_ALTO": "Ingesta registros de tráfico y amenazas de Palo Alto Networks NGFW para monitorear el uso de aplicaciones y la seguridad perimetral.", - "SONIC_WALL": "Ingesta registros de tráfico y amenazas de SonicWall NGFW para monitorear la seguridad perimetral y la actividad de red en UTMStack.", - "PFSENSE": "Ingesta registros del firewall y router pfSense con gestión unificada de amenazas para monitorear el tráfico de red y las amenazas.", - "MIKROTIK": "Ingesta registros de firewall, enrutamiento y redes inalámbricas de MikroTik RouterOS para monitorear la actividad y configuración de red.", - "AIX": "Recopila registros del sistema Unix IBM AIX, seguridad y auditoría para monitorear la actividad en plataformas IBM Power en UTMStack.", - "AS_400": "Recopila diarios del sistema y de auditoría de IBM AS/400 (IBM i) para monitorear la actividad de usuarios en plataformas OS/400 de rango medio.", - "ORACLE": "Ingesta registros de auditoría de Oracle Database para monitorear consultas, acceso y actividad privilegiada en tus bases de datos.", - "SURICATA": "Ingesta alertas de Suricata IDS/IPS y eventos de red para detectar intrusiones y tráfico malicioso en la red.", - "DECEPTIVE_BYTES": "Ingesta alertas de Deceptive Bytes desde su plataforma de engaño activo en endpoints para detectar actividad de atacantes de forma temprana.", - "GITHUB": "Ingesta registros de auditoría de GitHub para monitorear el acceso a repositorios, cambios de código y actividad organizacional para la seguridad del código fuente.", - "UTMSTACK": "Ingesta la telemetría propia de UTMStack de SIEM y XDR para monitorear el estado de la plataforma, la actividad interna y los eventos de autoauditoría.", - "NGINX": { - "name": "Nginx", - "description": "Ingesta los registros de acceso y error de Nginx para monitorear la actividad del servidor web, el tráfico del proxy inverso y las solicitudes de cliente." - }, - "APACHE": { - "name": "Apache", - "description": "Ingesta los registros de acceso y error de Apache HTTPD para monitorear la actividad del servidor web y las solicitudes de cliente." - }, - "APACHE2": { - "name": "Apache2", - "description": "Ingesta los registros del servidor web Apache2 (HTTPD) para monitorear el manejo de solicitudes, errores y el acceso en hosts Linux." - }, - "IIS": { - "name": "IIS", - "description": "Ingesta la actividad de acceso y archivos de registro de Internet Information Services (IIS) para monitorear el servicio web de Windows." - }, - "MYSQL": { - "name": "MySQL", - "description": "Ingesta la actividad de registros de MySQL para monitorear consultas, autenticación y acceso al almacén de datos." - }, - "POSTGRESQL": { - "name": "PostgreSQL", - "description": "Ingesta los registros de PostgreSQL para monitorear consultas, acceso y actividad en tus almacenes de datos." - }, - "MONGODB": { - "name": "MongoDB", - "description": "Ingesta la actividad de registros de MongoDB para monitorear el acceso a la base de datos documental, consultas y el comportamiento de la aplicación." - }, - "REDIS": { - "name": "Redis", - "description": "Ingesta la actividad de registros y telemetría de Redis para monitorear el uso del almacén de datos en memoria y las cargas de trabajo en tiempo real." - }, - "ELASTICsearch": { - "name": "ELASTICsearch", - "description": "Ingesta los registros de Elasticsearch para monitorear el motor de búsqueda y análisis y sus cargas de trabajo de aplicación." - }, - "LOGSTASH": { - "name": "Logstash", - "description": "Ingesta los registros de las tuberías de Logstash para monitorear la tubería de procesamiento de datos y sus transformaciones de eventos." - }, - "KIBANA": { - "name": "Kibana", - "description": "Ingesta los registros de Kibana para monitorear la capa de visualización y exploración de datos y su uso." - }, - "KAFKA": { - "name": "Apache Kafka", - "description": "Ingesta los registros de Apache Kafka para monitorear las tuberías de streaming en tiempo real, los brokers y el flujo de mensajes." - }, - "NATS": { - "name": "NATS", - "description": "Ingesta los registros de mensajería de NATS para monitorear el bus de mensajes, la conectividad y la entrega de eventos." - }, - "HAPROXY": { - "name": "HAProxy", - "description": "Ingesta los registros de HAProxy para monitorear el balanceo de carga, el tráfico del proxy y la disponibilidad de red." - }, - "TRAEFIK": { - "name": "Traefik", - "description": "Ingesta los registros de Traefik para monitorear el enrutamiento, el balanceo de carga y el tráfico del proxy entre cargas de trabajo." - }, - "OSQUERY": { - "name": "osquery", - "description": "Ingesta los registros de OsQuery para monitorear el estado del endpoint, las consultas y el inventario del sistema mediante solicitudes estilo SQL." - }, - "SYSLOG": { - "name": "Syslog", - "description": "Envía syslog (RFC 5424/3164) desde cualquier dispositivo o aplicación al extremo del collector para la ingesta centralizada de registros." - }, - "JSON": { - "name": "JSON Input", - "description": "Envía cargas de registros en JSON al extremo de ingesta para la captura estructurada de eventos de aplicaciones y scripts." - }, - "WINDOWS_SQL_SERVER": { - "name": "SQL Server Event Logs", - "description": "Collect Microsoft SQL Server audit and event records through the Windows Event Log and UTMStack agent." - }, - "WINDOWS_FILE_AUDITING": { - "name": "Windows File Access Auditing", - "description": "Collect Windows file access audit events through the Windows Event Log and UTMStack agent." - }, - "ELASTICSEARCH": { - "name": "Elasticsearch", - "description": "Ingesta los registros de Elasticsearch para monitorear el motor de búsqueda y análisis y sus cargas de trabajo de aplicación." - } }, - "edit": { - "title": "Editar integración" - }, - "allCategories": "Todas las categorías", - "customOnly": "Personalizadas" - }, - "dataProcessing": { - "title": "Procesamiento de datos", - "subtitle": "Estadísticas de ingesta y procesamiento: eventos recibidos, descartados por etapa, y las principales fuentes y tipos.", - "ingestion": { - "title": "Ingesta", - "last24h": "últimas 24 horas", - "noData": "Sin datos en esta ventana.", - "loadError": "No se pudieron cargar las stats de ingesta.", - "groupBy": { - "dataSource": "Por fuente de datos", - "dataType": "Por tipo de dato" - }, - "status": { - "received": "Recibidos", - "parsing_dropped": "Descartados (parseo)", - "analysis_dropped": "Descartados (análisis)", - "correlation_dropped": "Descartados (correlación)", - "all": "Todos los eventos" - } - }, - "filters": { - "title": "Filtros", - "new": "Nuevo filtro", - "search": "Buscar por ruta…", - "refresh": "Actualizar", - "retry": "Reintentar", - "empty": "Ningún filtro coincide.", - "loadError": "No se pudieron cargar los filtros.", - "toggleError": "No se pudo cambiar el estado del filtro", - "system": "Sistema", - "custom": "Personalizado", - "systemReadonly": "Los filtros del sistema son de solo lectura", - "view": "Ver", - "edit": "Editar", - "ownership": { - "all": "Todos", + "parsingFilters": { + "title": "Pipelines", + "subtitle": "Pipelines YAML que se aplican a los logs mientras se parsean durante la ingesta.", + "new": "Nuevo pipeline", + "search": "Buscar pipelines…", + "refresh": "Refrescar", + "view": "Ver", "system": "Sistema", - "custom": "Personalizados" - }, - "state": { - "all": "Todos", - "active": "Activos", - "inactive": "Inactivos" - }, - "col": { - "filter": "Filtro", - "type": "Tipo", - "active": "Activo", - "actions": "Acciones" - }, - "pageInfo": "{{from}}–{{to}} de {{count}}" - }, - "editor": { - "createTitle": "Nuevo filtro", - "editTitle": "Editar filtro", - "viewTitle": "Ver filtro", - "relPath": "Ruta", - "relPathHint": "Carpeta + archivo, p.ej. syslog/mi-filtro.yaml", - "content": "Pipeline (YAML)", - "contentHint": "Los pasos corren en orden: grok, rename, delete, plugins dynamic, …", - "save": "Guardar", - "saving": "Guardando…", - "saved": "Filtro guardado", - "saveError": "No se pudo guardar el filtro", - "cancel": "Cancelar", - "delete": "Eliminar", - "deleteConfirm": "¿Eliminar este filtro?", - "deleted": "Filtro eliminado", - "deleteError": "No se pudo eliminar el filtro" - }, - "kpi": { - "received": "Recibidos", - "dropped": "Descartados", - "dropRate": "{{rate}}% de descarte", - "stored": "Almacenados", - "throughput": "Rendimiento", - "perMin": "{{value}}/min", - "survival": "{{rate}}% conservados" - }, - "section": { - "overTime": "Eventos en el tiempo", - "top": "Top", - "dropReasons": "Razones de descarte" - }, - "live": { - "auto": "Auto" - }, - "pipeline": { - "title": "Pipeline de ingesta", - "stages": { - "received": "Recibidos", - "parsed": "Parseados", - "analyzed": "Analizados", - "stored": "Almacenados" - } - }, - "chart": { - "title": "Rendimiento en el tiempo", - "received": "Recibidos", - "dropped": "Descartados" - }, - "donut": { - "title": "Composición de descartes", - "dropped": "descartados" - }, - "breakdown": { - "title": "Top fuentes y tipos", - "bars": "Barras", - "treemap": "Treemap", - "showAll": "Ver los {{count}}", - "showLess": "Ver menos", - "lastSeen": "Visto por última vez", - "ago": "hace {{time}}" - } - }, - "datasources": { - "limitBanner": { - "title": "Límite de datasources superado.", - "message": "Tienes {{count}} datasources pero tu licencia cubre {{limit}}. Los logs de los datasources que exceden el límite se están descartando.", - "cta": "Gestionar licencia", - "dismiss": "Descartar" - }, - "title": "Fuentes de datos", - "total": "{{count}} en total", - "subtitle": "Agentes, integraciones y fuentes directas que envían eventos. El estado se deriva de la última vez que se vio cada fuente.", - "connectSource": "Conectar una fuente", - "loading": "Cargando fuentes de datos…", - "loadFailed": "No se pudieron cargar las fuentes de datos.", - "retry": "Reintentar", - "none": "Ninguna fuente coincide con esta vista.", - "ingestion": { - "title": "Ingestión", - "received": "eventos recibidos", - "none": "Sin ingestión en las últimas 24 horas.", - "ago24h": "hace 24h", - "now": "ahora" - }, - "usage": { - "title": "Fuentes de datos", - "ofUnlimited": "de ilimitado", - "ofLimit": "de {{limit}}", - "overLimit": "Por encima del límite licenciado — los datos que excedan el tope están en riesgo.", - "configured": "configuradas" - }, - "tabs": { - "all": "Todas", - "agent": "Agentes", - "puller": "Integraciones", - "direct": "Directas", - "offline": "Sin conexión" - }, - "toolbar": { - "searchPlaceholder": "Buscar por nombre…", - "list": "Lista", - "cards": "Tarjetas", - "refresh": "Actualizar" - }, - "labels": { - "filteredBy": "Filtrado por label", - "add": "Agregar label…", - "addFirst": "Agregar un label…", - "hint": "Escribí un label y presioná Enter para agregarlo. Los cambios se guardan solos." - }, - "status": { - "live": "Activa", - "idle": "Inactiva", - "offline": "Sin conexión" - }, - "kind": { - "agent": "Agente", - "puller": "Integración", - "direct": "Directa" - }, - "cols": { - "source": "Fuente", - "type": "Tipo", - "status": "Estado", - "events24h": "Eventos 24h", - "lastSeen": "Vista por última vez" + "user": "Personalizado", + "loading": "Cargando pipelines…", + "loadError": "No se pudieron cargar los pipelines.", + "retry": "Reintentar", + "empty": "Ningún pipeline coincide con esta vista.", + "tabs": { + "all": "Todos", + "active": "Activos", + "inactive": "Inactivos", + "system": "Sistema", + "user": "Personalizados" + }, + "cols": { + "filter": "Pipeline", + "type": "Tipo", + "active": "Activo", + "dataTypes": "Tipos de dato", + "order": "Orden", + "moveUp": "Subir", + "moveDown": "Bajar", + "actions": "Acciones" + }, + "editor": { + "titleNew": "Nuevo pipeline", + "titleEdit": "Editar pipeline", + "titleSystem": "Pipeline (sistema)", + "name": "Nombre", + "namePlaceholder": "Mi pipeline custom", + "nameHint": "Se guardará como {{file}}", + "namePending": "Elige un nombre — será el nombre del archivo.", + "content": "Contenido (pipeline YAML)", + "contentHint": "Una definición válida en pipeline: YAML.", + "readOnly": "Pipeline de sistema — solo lectura. Solo puedes activarlo o desactivarlo.", + "save": "Guardar", + "saving": "Guardando…", + "delete": "Eliminar", + "confirmDelete": "Confirmar eliminación", + "cancel": "Cancelar", + "test": "Test" + }, + "toast": { + "saved": "Pipeline guardado", + "saveError": "No se pudo guardar el pipeline", + "deleted": "Pipeline eliminado", + "deleteError": "No se pudo eliminar el pipeline", + "activateError": "No se pudo cambiar el estado del pipeline", + "nameRequired": "El nombre es obligatorio", + "contentRequired": "El contenido es obligatorio", + "orderError": "No se pudo cambiar el orden del pipeline" + }, + "visual": { + "visualTab": "Visual", + "codeTab": "Código", + "codeOnly": "Cambia a Código — este contenido no se puede mostrar de forma visual.", + "cantParse": "No se puede abrir el editor visual: {{error}}", + "dataTypes": "Tipos de dato", + "steps": "Pasos", + "noSteps": "Aún no hay pasos.", + "addStep": "Agregar paso:", + "removeStep": "Eliminar paso", + "moveUp": "Subir", + "moveDown": "Bajar", + "whereHint": "condición opcional (CEL)", + "addValue": "Agregar valor", + "addPattern": "Agregar patrón", + "rawHint": "Este processor se edita como YAML directo.", + "rawNotMap": "Debe ser un conjunto de campos clave: valor.", + "dataTypesPick": "Elegir tipos de dato", + "dataTypesSearch": "Buscar tipos de dato…", + "dataTypesNone": "Sin tipos de dato", + "dataTypesAdd": "Agregar \"{{value}}\"", + "insertPattern": "Insertar patrón regex", + "patternSearch": "Buscar patrones…", + "patternNone": "Sin patrones", + "newPattern": "Nuevo patrón…", + "createInsert": "Crear e insertar", + "patternCreated": "Patrón \"{{name}}\" creado", + "patternCreateError": "No se pudo crear el patrón", + "patternIdInvalid": "El ID debe empezar con letra o _ y usar solo letras, dígitos o _", + "patternDefRequired": "La definición es obligatoria", + "parameters": "Parámetros", + "paramsKey": "Clave", + "paramsValue": "Valor", + "entry": "Entrada {{n}}", + "order": "orden {{n}}", + "orderLabel": "Orden", + "removeEntry": "Eliminar entrada", + "addEntry": "Añadir entrada de pipeline", + "collapse": "Contraer", + "expand": "Expandir", + "splitHint": "Vacío equivale a un espacio por defecto — en el YAML siempre aparece como fieldSplit: \" \"." + }, + "allDataTypes": "Todos los tipos de dato", + "testPipeline": "Test pipeline" + }, + "alertingRules": { + "title": "Reglas de Alertas", + "subtitle": "Reglas de correlación que convierten eventos en alertas. Actívalas, ajústalas o crea las tuyas.", + "new": "Nueva regla", + "refresh": "Actualizar", + "empty": "No hay reglas que coincidan.", + "loadError": "No se pudieron cargar las reglas.", + "retry": "Reintentar", + "deleteConfirm": "¿Eliminar la regla «{{name}}»?", + "adversary": { + "origin": "Origen", + "target": "Destino" + }, + "state": { + "active": "Activa", + "inactive": "Inactiva" + }, + "owner": { + "system": "Sistema", + "custom": "Personalizada" + }, + "toolbar": { + "search": "Buscar reglas…", + "allCategories": "Todas las categorías", + "allAdversaries": "Todos los adversarios", + "allStates": "Todos los estados", + "allOwners": "Todos los orígenes", + "allDataTypes": "Todos los tipos" + }, + "table": { + "name": "Regla", + "category": "Categoría", + "technique": "Técnica", + "adversary": "Adversario", + "impact": "Impacto", + "active": "Activa", + "dataTypes": "Tipos de dato", + "selectAll": "Seleccionar todo", + "selectRow": "Seleccionar {{name}}" + }, + "export": { + "all": "Exportar todo", + "selected": "Exportar ({{count}})", + "error": "No se pudieron exportar las reglas" + }, + "view": { + "description": "Descripción", + "details": "Detalles", + "impact": "Impacto (C·I·D)", + "dataTypes": "Tipos de dato", + "updated": "Actualizada", + "relPath": "Ruta", + "definition": "Condición (CEL)", + "correlationSteps": "Pasos de correlación", + "correlation": "Correlación", + "groupBy": "Agrupar por", + "deduplicateBy": "Deduplicar por", + "references": "Referencias" + }, + "editor": { + "createTitle": "Nueva regla", + "edit": "Editar", + "delete": "Eliminar", + "export": "Exportar", + "cancel": "Cancelar", + "save": "Guardar", + "metadata": "Metadatos", + "name": "Nombre", + "confidentiality": "Confidencialidad", + "integrity": "Integridad", + "availability": "Disponibilidad", + "dataTypes": "Tipos de dato", + "dataTypesHint": "separados por coma", + "activeOnSave": "Activa", + "definitionSection": "Definición", + "where": "Condición (CEL)", + "whereHint": "Expresión CEL evaluada por evento", + "correlationSteps": "Pasos de correlación", + "correlationStepsHint": "array JSON", + "jsonArray": "array JSON", + "nameRequired": "El nombre es obligatorio", + "definitionRequired": "La condición es obligatoria", + "invalidJson": "Un campo de la definición tiene JSON inválido", + "addStep": "Agregar paso de correlación", + "step": "Paso {{n}}", + "removeStep": "Quitar paso", + "indexPattern": "Patrón de índice", + "within": "Ventana", + "count": "Cantidad", + "conditions": "Condiciones", + "field": "Campo", + "value": "Valor", + "addCondition": "Agregar condición", + "orGroup": "Grupo Or {{n}}", + "addOr": "Agregar grupo Or", + "removeOr": "Quitar", + "fieldsHint": "nombres de campo", + "referencesHint": "URLs", + "visual": "Visual", + "code": "Código", + "dataTypesPick": "Seleccionar…", + "dataTypesSearch": "Buscar tipos de dato…", + "dataTypesNone": "Sin tipos de dato", + "visualTab": "Visual", + "codeTab": "Código", + "yamlError": "No se puede aplicar el YAML: {{error}}", + "test": "Test" + }, + "toast": { + "activated": "Regla activada", + "deactivated": "Regla desactivada", + "toggleError": "No se pudo cambiar el estado de la regla", + "deleted": "Regla eliminada", + "deleteError": "No se pudo eliminar la regla", + "created": "Regla creada", + "saved": "Regla guardada", + "saveError": "No se pudo guardar la regla" + }, + "operator": { + "filter_term": "igual (term)", + "must_not_term": "distinto (term)", + "filter_match": "coincide (texto)", + "must_not_match": "no coincide (texto)" + }, + "where": { + "matchPrefix": "Coincide con", + "all": "todas", + "any": "cualquiera", + "matchSuffix": "de estas condiciones:", + "negate": "Negar", + "listHint": "separado por comas", + "advanced": "Esta condición usa CEL avanzado — edítala en Código o reconstrúyela visualmente.", + "and": "Y", + "or": "O" + }, + "celOp": { + "exists": "existe", + "equals": "igual a", + "equalsIgnoreCase": "igual (sin may.)", + "contains": "contiene", + "oneOf": "es uno de", + "containsAll": "contiene todos", + "startsWith": "empieza con", + "endsWith": "termina con", + "regexMatch": "regex", + "lessThan": "<", + "lessOrEqual": "≤", + "greaterThan": ">", + "greaterOrEqual": "≥", + "inCIDR": "en CIDR", + "isHour": "la hora es", + "isMinute": "el minuto es", + "isDayOfWeek": "el día es", + "isWeekend": "es fin de semana", + "isWorkDay": "es día hábil", + "isBetweenTime": "hora entre" + }, + "import": { + "button": "Importar", + "error": "Falló la importación", + "resultTitle": "Resultados de la importación", + "approved": "Aprobadas", + "rejected": "Rechazadas", + "done": "Listo" + }, + "test": "Test" + }, + "regexPatterns": { + "title": "Expresiones regulares", + "subtitle": "Expresiones regulares reutilizables referenciadas por los filtros de parseo.", + "new": "Nuevo patrón", + "search": "Buscar patrones…", + "refresh": "Actualizar", + "view": "Ver", + "system": "Sistema", + "user": "Personalizado", + "loading": "Cargando patrones…", + "loadError": "No se pudieron cargar los patrones.", + "retry": "Reintentar", + "empty": "Ningún patrón coincide con esta vista.", + "tabs": { + "all": "Todos", + "system": "Sistema", + "user": "Personalizados" + }, + "cols": { + "pattern": "Patrón", + "definition": "Definición", + "type": "Tipo" + }, + "editor": { + "titleNew": "Nuevo patrón", + "patternId": "ID del patrón", + "patternIdHint": "Nombre único referenciado desde los filtros.", + "description": "Descripción", + "descriptionPlaceholder": "Qué reconoce este patrón (opcional)", + "definition": "Definición (regex)", + "definitionHint": "Una expresión regular. Puede referenciar otros patrones.", + "readOnly": "Patrón de sistema — solo lectura.", + "save": "Guardar", + "saving": "Guardando…", + "delete": "Eliminar", + "confirmDelete": "Confirmar eliminación", + "cancel": "Cancelar" + }, + "toast": { + "saved": "Patrón guardado", + "saveError": "No se pudo guardar el patrón", + "deleted": "Patrón eliminado", + "deleteError": "No se pudo eliminar el patrón", + "patternIdRequired": "El ID del patrón es obligatorio", + "definitionRequired": "La definición es obligatoria" + } }, - "time": { - "justNow": "ahora mismo", - "minutesAgo": "hace {{count}}m", - "hoursAgo": "hace {{count}}h", - "daysAgo": "hace {{count}}d" + "soar": { + "title": "SOAR", + "subtitle": "Flujos de respuesta automática: las condiciones matchean una alerta y los comandos corren en el agente.", + "comingSoon": "Próximamente", + "console": { + "loading": "Cargando agentes…", + "loadError": "No se pudieron cargar los agentes.", + "pickAgent": "Selecciona un agente", + "pickAgentHint": "Elige un agente de la lista para abrir su consola interactiva.", + "lockedAgent": "Control remoto deshabilitado" + }, + "search": "Buscar flujos…", + "refresh": "Refrescar", + "new": "Nuevo flujo", + "view": "Ver", + "system": "Sistema", + "loading": "Cargando flujos…", + "loadError": "No se pudieron cargar los flujos.", + "retry": "Reintentar", + "empty": "Ningún flujo coincide con esta vista.", + "templates": { + "title": "Nuevo flujo", + "subtitle": "Elige una plantilla de acción o empieza desde cero.", + "loading": "Cargando plantillas…", + "loadError": "No se pudieron cargar las plantillas.", + "empty": "No hay plantillas disponibles.", + "cancel": "Cancelar", + "scratch": "Empezar desde cero" + }, + "tabs": { + "flows": "Flujos", + "executions": "Historial de ejecuciones", + "all": "Todos", + "active": "Activos", + "inactive": "Inactivos", + "system": "Sistema", + "user": "Propios" + }, + "cols": { + "flow": "Flujo", + "platform": "Plataforma", + "conditions": "Condiciones", + "commands": "Comandos", + "active": "Activo", + "lastRun": "Última ejecución", + "failedRuns_one": "{{count}} ejecución fallida", + "failedRuns_other": "{{count}} ejecuciones fallidas" + }, + "operator": { + "IS": "es", + "IS_NOT": "no es", + "CONTAINS": "contiene", + "NOT_CONTAINS": "no contiene", + "EXISTS": "existe", + "NOT_EXISTS": "no existe", + "START_WITH": "comienza con", + "NOT_START_WITH": "no comienza con", + "ENDS_WITH": "termina con", + "NOT_ENDS_WITH": "no termina con", + "IS_ONE_OF": "es uno de", + "IS_NOT_ONE_OF": "no es uno de" + }, + "toast": { + "created": "Flujo creado", + "saved": "Flujo guardado", + "saveError": "No se pudo guardar el flujo", + "deleted": "Flujo eliminado", + "deleteError": "No se pudo eliminar el flujo", + "activateError": "No se pudo cambiar el estado del flujo" + }, + "editor": { + "createTitle": "Nuevo flujo", + "visualTab": "Visual", + "codeTab": "Código", + "name": "Nombre", + "description": "Descripción", + "conditions": "Condiciones", + "conditionsHint": "El flujo corre cuando una alerta cumple TODAS estas condiciones.", + "field": "campo", + "value": "valor", + "valueList": "valores separados por coma", + "addCondition": "Agregar condición", + "commands": "Comandos", + "commandsHint": "Se ejecutan en orden en el agente. Usa $(field.path) para valores de la alerta y $[variables.NAME] para variables guardadas.", + "addCommand": "Agregar comando", + "templatesButton": "Comandos comunes", + "templates": { + "isolate": "Aislar de la red", + "shutdown": "Apagar máquina", + "killProcess": "Matar proceso", + "logout": "Cerrar sesión", + "disableUser": "Deshabilitar usuario", + "blockIp": "Bloquear IP", + "restart": "Reiniciar la máquina", + "uninstall": "Desinstalar aplicación" + }, + "connector": { + "always": "siempre", + "success": "si tuvo éxito", + "failure": "si falló" + }, + "agentPlatform": "Plataforma del agente", + "shell": "Shell", + "shellAuto": "auto", + "whereToRun": "Dónde ejecutar", + "run": { + "all": "Todos los agentes", + "specific": "Un agente", + "except": "Todos excepto", + "allHint": "Se ejecuta en todos los agentes que coincidan con esta plataforma." + }, + "selectAgentPlaceholder": "Selecciona un agente…", + "excludedAgentsHint": "escribe un hostname y presiona Enter", + "save": "Guardar", + "delete": "Eliminar", + "confirmDelete": "Confirmar eliminación", + "cancel": "Cancelar", + "yamlError": "No se puede aplicar el YAML: {{error}}", + "nameRequired": "El nombre es obligatorio", + "conditionsRequired": "Se requiere al menos una condición con campo", + "commandsRequired": "Se requiere al menos un comando", + "httpUrlInvalid": "El nodo HTTP \"{{id}}\" tiene una URL inválida — debe ser una URL http(s) válida.", + "httpBodyInvalid": "El cuerpo del nodo HTTP \"{{id}}\" no es JSON válido: {{error}}", + "incidentNameRequired": "El nodo de incidente \"{{id}}\" requiere un nombre.", + "mailToRequired": "El nodo de correo \"{{id}}\" requiere al menos un destinatario.", + "mailAddressInvalid": "El nodo de correo \"{{id}}\" tiene una dirección {{field}} no válida: {{address}}.", + "mailSubjectRequired": "El nodo de correo \"{{id}}\" requiere un asunto.", + "identityModalTitle": "Detalles del flujo", + "platformRequired": "La plataforma del agente es obligatoria", + "nameLabel": "Nombre", + "namePlaceholder": "Nombre del flujo", + "descriptionLabel": "Descripción", + "descriptionHint": "¿Qué hace este flujo? (opcional)", + "when": "Cuando", + "whenTitle": "Una alerta cumple todas estas condiciones", + "on": "En", + "onTitle": "El agente que coincide", + "thenRun": "Entonces ejecuta", + "thenTitle": "Estos comandos, en orden", + "selectField": "Elegir un campo…", + "selectPlatform": "Elegir una plataforma…", + "searchAgents": "Buscar agentes…", + "noAgents": "Sin agentes", + "insertInto": "Insertar en el comando {{n}}:", + "insertField": "Campo de alerta", + "variables": "Variables", + "canvas": { + "node": "Nodo", + "deleteNode": "Eliminar nodo", + "id": "ID", + "kind": "Tipo", + "executor": "Ejecutor", + "commandLabel": "Comando", + "paramsJson": "Parámetros (JSON)", + "dragToResize": "Arrastra para redimensionar", + "templatesLabel": "Plantillas", + "templatesNeedPlatform": "Selecciona primero la plataforma destino", + "handlesHint": "Arrastra desde el conector verde (abajo-izquierda) para on_success y desde el rojo (abajo-derecha) para on_error. Varias conexiones = paralelo. Varias conexiones a un mismo nodo = AND-join.", + "invalidJson": "JSON inválido", + "hidePalette": "Ocultar paleta", + "hideInspector": "Ocultar inspector", + "paletteLabel": "Paleta", + "nodeShort": "Nodo", + "showPanel": "Mostrar {{name}}", + "platform": "Plataforma", + "shell": "Shell", + "any": "cualquiera", + "auto": "auto", + "runOn": "Ejecutar en", + "runAutoTitle": "Se ejecuta en el host que generó la alerta", + "runSpecificTitle": "Fijar a un host (o una plantilla como $(alert.foo))", + "runExceptTitle": "Se ejecuta en el host que generó la alerta, excluyendo los de la lista", + "runAutoLabel": "fuente de alerta", + "runSpecificLabel": "un host", + "runExceptLabel": "todos excepto", + "runAutoHint": "Se ejecuta en $(alert.dataSource) — el host que generó la alerta.", + "pickHost": "elige un host…", + "orTemplateHint": "O escribe una plantilla — $(alert.field) se resuelve en cada ejecución.", + "addExclusion": "añadir exclusión", + "searchAgents": "buscar agentes…", + "noAgents": "sin agentes", + "insertField": "Insertar campo", + "alert": "Alerta", + "wholeOutput": "salida completa (edita la ruta)", + "noAncestorsHint": "Aún no hay ancestros de enriquecimiento — añade un nodo de enriquecimiento previo para exponer su salida aquí.", + "inserts": "inserta", + "conditionalHint": "Todas las condiciones deben coincidir. Coincidencia → rama de éxito (verde); fallo → rama de error (rojo).", + "http": { + "url": "URL", + "urlInvalid": "URL http(s) inválida.", + "method": "Método", + "body": "Cuerpo (JSON)", + "bodyInvalid": "JSON inválido", + "headers": "Encabezados HTTP", + "params": "Parámetros de consulta", + "key": "Clave", + "value": "Valor", + "addHeader": "Agregar encabezado", + "addParam": "Agregar parámetro" + }, + "incident": { + "name": "Nombre del incidente", + "namePlaceholder": "Ej. Inicio de sesión sospechoso en $(alert.dataSource)", + "description": "Descripción", + "descriptionPlaceholder": "Contexto opcional para los responsables. Plantillas como $(alert.name) se interpolan." + }, + "llm": { + "prompt": "Prompt", + "hint": "El modelo siempre responde con un único objeto JSON que incluye la propiedad \"result\"; el backend garantiza ese formato aunque el modelo se desvíe. Los nodos hijos la consultan con $({{nodeId}}.result) o campos específicos." + }, + "mail": { + "to": "Para (separados por coma)", + "cc": "CC (separados por coma, opcional)", + "addressInvalid": "Dirección de correo no válida: {{address}}", + "subject": "Asunto", + "subjectPlaceholder": "Ej. Alerta en $(alert.dataSource)", + "body": "Cuerpo", + "bodyPlaceholder": "Contenido del mensaje. Plantillas como $(alert.name) se interpolan." + }, + "notify": { + "level": "Level", + "message": "Message", + "messagePlaceholder": "Notification text. Templates like $(alert.name) are interpolated." + } + } + }, + "executions": { + "search": "Buscar por ID de alerta…", + "all": "Todas", + "loading": "Cargando ejecuciones…", + "loadError": "No se pudieron cargar las ejecuciones.", + "retry": "Reintentar", + "empty": "Aún no hay ejecuciones.", + "cols": { + "status": "Estado", + "flow": "Flujo", + "command": "Comando / Acción", + "agent": "Agente", + "date": "Fecha", + "retries": "Reintentos", + "node": "Nodo" + }, + "filters": { + "source": "Origen", + "allSources": "Todos los orígenes" + }, + "manual": "Consola interactiva" + }, + "executionStatus": { + "WAITING": "En espera", + "PENDING": "Pendiente", + "EXECUTING": "Ejecutando", + "EXECUTED": "Ejecutado", + "FAILED": "Fallido", + "DEAD": "Inaccesible" + }, + "executionOrigin": { + "FLOW": "Flujo", + "MANUAL": "Manual" + }, + "nonExecutionCause": { + "AGENT_OFFLINE": "Agente offline", + "AGENT_NOT_FOUND": "Agente no encontrado", + "UNKNOWN": "Desconocido" + }, + "kpi": { + "flows": "Flujos totales", + "active": "Activos", + "runs24h": "Ejecuciones (24h)", + "failed24h": "Fallidas (24h)" + }, + "neverRun": "nunca", + "create": { + "title": "Nuevo flujo", + "modeManual": "Crear manualmente", + "modeAi": "Con IA", + "aiLocked": "Active SOC-AI y configúrelo para usar esto.", + "name": "Nombre del flujo", + "namePlaceholder": "p. ej. Bloquear IP por fallos repetidos", + "aiDescriptionLabel": "¿Qué debe hacer este flujo?", + "aiDescriptionPlaceholder": "p. ej. Ante una alerta crítica, buscar la IP de origen en inteligencia de amenazas y bloquearla en el firewall", + "aiCreate": "Crear con IA", + "manualContinue": "Continuar" + } }, - "drawer": { - "loading": "Cargando…", - "loadFailed": "No se pudo cargar la fuente de datos.", - "statsIdentity": "Stats e identidad", - "metadata": "Metadata", - "labelsSection": "Labels", - "dangerZone": "Zona de peligro", - "rows": { - "events24h": "Eventos 24h", - "lastSeen": "Vista por última vez", - "discovered": "Descubierta", - "kind": "Tipo de origen", - "dataType": "Tipo de dato", - "ip": "IP", - "id": "ID" - }, - "dangerText": "Eliminar quita esta fuente del registro. Los eventos históricos siguen disponibles en el Log Explorer; si la fuente sigue enviando datos, se redescubrirá.", - "delete": "Eliminar fuente", - "confirmDelete": "Confirmar eliminación", - "cancel": "Cancelar", - "viewLogs": "Ver logs", - "trend": "Tendencia de ingesta", - "noTrend": "No se recibieron eventos en esta ventana", - "logGap": "Último evento {{since}} — posible interrupción de logs" + "compliance": { + "title": "Compliance", + "subtitle": "Evalúa tu postura frente a frameworks de seguridad — mira qué controles se cumplen y cuáles no.", + "comingSoon": "Próximamente.", + "tabs": { + "frameworks": "Frameworks", + "schedule": "Programación", + "controls": "Controles" + }, + "search": "Buscar frameworks…", + "refresh": "Actualizar", + "loading": "Cargando frameworks…", + "loadError": "No se pudieron cargar los informes", + "retry": "Reintentar", + "empty": "Ningún framework coincide.", + "notEvaluated": "Sin evaluar", + "controlsCount": "{{n}} controles", + "enabledLabel": "Activo", + "runReport": "Correr reporte", + "backToFrameworks": "Volver a frameworks", + "statusAuto": "Auto (evaluado)", + "overrideError": "No se pudo actualizar el estado", + "noteError": "No se pudo guardar la nota", + "notes": { + "title": "Notas", + "placeholder": "Agregar una nota…", + "save": "Guardar", + "cancel": "Cancelar" + }, + "reasonModal": { + "title": "Motivo requerido", + "description": "Indica el motivo del cambio de estado. Se registrará.", + "label": "Motivo", + "placeholder": "Explica por qué cambias el estado de este control…", + "confirm": "Confirmar cambio", + "cancel": "Cancelar" + }, + "coverageLabel": "Cobertura", + "activityLabel": "Actividad", + "evidenceLabel": "Evidencia", + "seeMore": "Ver más", + "seeLess": "Ver menos", + "evaluating": "Evaluando framework…", + "complianceScore": "Puntaje de compliance", + "generatedAt": "Generado {{date}}", + "reportError": "No se pudo generar el reporte.", + "coverage": "{{n}} reglas", + "activity": "{{n}} alertas", + "status": { + "COMPLIANT": "Cumple", + "NON_COMPLIANT": "No cumple", + "AT_RISK": "En riesgo", + "NOT_COVERED": "Sin cobertura", + "OUT_OF_SCOPE": "Fuera de alcance", + "PENDING": "Pendiente", + "label": "Estado", + "NOT_EVALUATED": "Sin evaluar" + }, + "toast": { + "toggleError": "No se pudo cambiar el estado del framework", + "reportGenerated": "Reporte generado", + "reportError": "No se pudo generar el reporte" + }, + "schedule": { + "new": "Nueva programación", + "loading": "Cargando programaciones…", + "loadError": "No se pudieron cargar las programaciones.", + "empty": "Aún no hay programaciones.", + "edit": "Editar", + "delete": "Eliminar", + "newTitle": "Nueva programación", + "editTitle": "Editar programación", + "framework": "Framework", + "cadenceLabel": "Cadencia", + "cronHint": "Cron de 5 campos (min hora día mes díaSemana).", + "recipientsHint": "Emails separados por coma. Vacío = solo guarda el snapshot.", + "save": "Guardar", + "cancel": "Cancelar", + "frameworkRequired": "El framework es obligatorio", + "cronRequired": "La programación (cron) es obligatoria", + "cadence": { + "daily": "Diaria", + "weekly": "Semanal", + "monthly": "Mensual", + "custom": "Personalizada" + }, + "toast": { + "saved": "Programación guardada", + "saveError": "No se pudo guardar la programación", + "deleted": "Programación eliminada", + "deleteError": "No se pudo eliminar la programación" + }, + "to": "Para", + "cc": "Cc", + "toRequired": "Se requiere al menos un destinatario", + "windowDays": "Ventana del informe (días)", + "windowDaysShort": "sobre {{days}}d", + "windowDaysHint": "Cuánto abarca el informe. Independiente de cada cuánto se ejecuta." + }, + "frameworks": { + "new": "Nuevo framework", + "edit": "Editar", + "createTitle": "Nuevo framework", + "visualTab": "Visual", + "codeTab": "Código", + "key": "Clave", + "name": "Nombre", + "description": "Descripción", + "source": "Fuente", + "sections": "Secciones", + "sectionKey": "clave de sección", + "sectionName": "Nombre de sección", + "requirements": "Requisitos", + "reqId": "id req", + "reqName": "Nombre del requisito", + "addSection": "Agregar sección", + "addRequirement": "Agregar requisito", + "satisfiedBy": "satisfecho por controles", + "searchControls": "Buscar controles…", + "noControls": "Sin controles", + "save": "Guardar", + "delete": "Eliminar", + "confirmDelete": "Confirmar eliminación", + "cancel": "Cancelar", + "yamlError": "No se puede aplicar el YAML: {{error}}", + "keyRequired": "La clave es obligatoria", + "nameRequired": "El nombre es obligatorio", + "toast": { + "created": "Framework creado", + "saved": "Framework guardado", + "saveError": "No se pudo guardar el framework", + "deleted": "Framework eliminado", + "deleteError": "No se pudo eliminar el framework" + }, + "createControl": "Crear nuevo control…", + "createNamed": "Crear control \"{{name}}\"…" + }, + "controls": { + "search": "Buscar controles…", + "allFamilies": "Todas las familias", + "new": "Nuevo control", + "loading": "Cargando controles…", + "loadError": "No se pudieron cargar los controles.", + "empty": "Ningún control coincide.", + "showingOf": "Mostrando {{shown}} de {{total}}", + "id": "ID", + "name": "Nombre", + "family": "Familia", + "familyName": "Familia", + "scope": "Alcance", + "source": "Fuente", + "notInLibrary": "Control no encontrado en la biblioteca", + "scopeOpt": { + "data": "Datos", + "governance": "Gobernanza" + }, + "strategy": "Estrategia", + "statement": "Enunciado", + "remediation": "Remediación", + "checks": "Checks", + "checksHint": "Cada check corre una consulta SQL en OpenSearch y aplica una regla para decidir pasa/falla.", + "checkKey": "clave", + "checkName": "Nombre del check", + "rule": { + "MIN_HITS_REQUIRED": "Mín hits requeridos", + "THRESHOLD_MAX": "Umbral máx" + }, + "ruleNone": "Sin regla", + "ruleValue": "valor", + "addCheck": "Agregar check", + "createTitle": "Nuevo control", + "visualTab": "Visual", + "codeTab": "Código", + "save": "Guardar", + "delete": "Eliminar", + "confirmDelete": "Confirmar eliminación", + "cancel": "Cancelar", + "yamlError": "No se puede aplicar el YAML: {{error}}", + "idRequired": "El ID es obligatorio", + "nameRequired": "El nombre es obligatorio", + "anyDataType": "Cualquier tipo de dato", + "addFilter": "Añadir filtro", + "filterField": "log.eventCode", + "filterValue": "valor", + "filterValues": "a, b, c", + "toast": { + "created": "Control creado", + "saved": "Control guardado", + "saveError": "No se pudo guardar el control", + "deleted": "Control eliminado", + "deleteError": "No se pudo eliminar el control" + } + }, + "doc": { + "title": "Reporte de Compliance", + "print": "Imprimir / PDF", + "controlsEvaluated": "{{n}} controles evaluados", + "executiveSummary": "Resumen Ejecutivo", + "bySection": "Hallazgos por Sección", + "footer": "{{framework}} — Reporte de compliance generado {{date}} · {{brand}}", + "download": "Descargar PDF", + "downloadError": "No se pudo descargar el PDF", + "error": "No se pudo generar el PDF", + "building": "Generando el documento…" + }, + "locked": { + "badge": "Enterprise", + "upgrade": "Pasar a Enterprise", + "upsell": "Este framework/control requiere la edición Enterprise." + }, + "run": "Ejecutar evaluación", + "runError": "La evaluación falló", + "noReportYet": "Este framework aún no se ha evaluado.", + "window": "ventana {{from}} → {{to}}", + "scoredOver": "{{compliant}} de {{evaluated}} requisitos cumplidos · {{total}} en el framework", + "editStale": "Registrado cuando el motor decía {{was}}; ahora dice {{now}}", + "checkResults": "Resultados de los checks", + "verdict": "Veredicto registrado", + "engineSaid": "el motor decía", + "hits": "coincidencias", + "noDataFor": "sin datos de {{dataType}} en la ventana", + "setStatus": "Cambiar estado", + "outcome": { + "PASSED": "Pasó", + "FAILED": "Falló", + "NOT_APPLICABLE": "Sin datos", + "ERROR": "Error" + }, + "system": "Del sistema", + "addNote": "Añadir nota", + "noteModal": { + "title": "Nota", + "description": "Se guarda en el informe. No cambia el estado del control.", + "placeholder": "Remediación en curso — ticket OPS-4412, cierre fin de trimestre." + }, + "history": { + "title": "Score en el tiempo", + "score": "Score de cumplimiento", + "coverage": "Evaluados", + "error": "No se pudo cargar el histórico" + } }, - "toast": { - "labelsUpdated": "Labels actualizados", - "labelsFailed": "No se pudieron actualizar los labels", - "deleted": "Fuente eliminada", - "deleteFailed": "No se pudo eliminar" + "taggingRules": { + "title": "Reglas de etiquetado", + "subtitle": "Etiqueta automáticamente las alertas que cumplan las condiciones.", + "new": "Nueva regla", + "refresh": "Actualizar", + "empty": "Aún no hay reglas de etiquetado.", + "loadError": "No se pudieron cargar las reglas de etiquetado.", + "retry": "Reintentar", + "deleteConfirm": "¿Eliminar la regla \"{{name}}\"? Las alertas futuras que cumplan sus condiciones dejarán de etiquetarse.", + "toolbar": { + "search": "Buscar por nombre de regla…", + "allTags": "Todas las etiquetas" + }, + "table": { + "rule": "Regla", + "tags": "Etiquetas", + "conditions": "Condiciones", + "modifiedBy": "Modificado por", + "modifiedDate": "Modificado" + }, + "drawer": { + "createTitle": "Nueva regla de etiquetado", + "edit": "Editar", + "delete": "Eliminar", + "save": "Guardar", + "create": "Crear", + "cancel": "Cancelar" + }, + "form": { + "basics": "Datos básicos", + "name": "Nombre de la regla", + "namePlaceholder": "p. ej. Fuerza bruta SSH interna", + "description": "Descripción", + "descriptionPlaceholder": "Por qué existe esta regla y qué etiqueta.", + "tags": "Etiquetas a aplicar", + "noTags": "No hay etiquetas seleccionadas.", + "addTag": "Agregar etiqueta", + "removeTag": "Quitar", + "noCatalog": "Aún no hay etiquetas en el catálogo.", + "createTag": "Crear etiqueta", + "newTagName": "Nombre de la nueva etiqueta", + "conditions": "Condiciones (deben cumplirse TODAS)", + "noConditions": "Se requiere al menos una condición.", + "addCondition": "Agregar condición", + "removeCondition": "Quitar condición", + "valuePlaceholder": "Valor", + "valueListPlaceholder": "Valores separados por comas", + "incomplete": "Completa el nombre de la regla, la descripción, al menos una etiqueta y todas las condiciones." + }, + "view": { + "description": "Descripción", + "tags": "Etiquetas", + "conditions": "Condiciones", + "audit": "Auditoría", + "createdBy": "Creado por", + "createdDate": "Creado", + "modifiedBy": "Modificado por", + "modifiedDate": "Modificado" + }, + "toast": { + "created": "Regla \"{{name}}\" creada.", + "updated": "Regla \"{{name}}\" actualizada.", + "deleted": "Regla \"{{name}}\" eliminada.", + "createError": "No se pudo crear la regla.", + "updateError": "No se pudo actualizar la regla.", + "deleteError": "No se pudo eliminar la regla." + }, + "deleteTitle": "Eliminar regla de etiquetado" + }, + "threatIntel": { + "header": { + "matchedInEnv": "coincidencias en tu entorno", + "export": "Exportar IOCs", + "exporting": "Exportando…", + "noInstanceIocs": "Sin indicadores de instancia — mostrando datos genéricos", + "noInstanceIocsHint": "No se observaron indicadores en tus alertas — se muestran datos genéricos de feeds." + }, + "overview": { + "title": "Coincidencias de IOCs", + "totalIndicators": "indicadores totales", + "families": { + "ip": "IP", + "url": "URL", + "domain": "Dominio", + "signatures": "Firmas" + } + }, + "notConfigured": { + "title": "Threat Intelligence no está configurado", + "body": "Contacta a tu administrador para conectar una instancia de Cyber Mantra / ThreatWinds para este entorno." + }, + "lookup": { + "title": "Busca cualquier indicador", + "placeholder": "Pega una IP, dominio, hash, URL o CVE — revisaremos feeds y tu entorno", + "button": "Buscar", + "busy": "Buscando…" + }, + "tabs": { + "iocs": "IOCs", + "actors": "Actores de amenaza", + "feeds": "Feeds", + "analyst": "Analista de IA" + }, + "toolbar": { + "searchPlaceholders": { + "iocs": "Busca IOC, etiqueta, fuente…", + "actors": "Busca actores, alias, técnicas…", + "feeds": "Busca feeds…" + }, + "last24h": "Últimas 24 horas", + "filters": "Filtros", + "refresh": "Actualizar" + }, + "iocs": { + "table": { + "type": "Tipo", + "indicator": "Indicador", + "reputation": "Reputación", + "tags": "Etiquetas", + "lastSeen": "Última vez visto" + }, + "empty": "Sin coincidencias de IOCs.", + "loadingMore": "Cargando más…", + "loadedProgress": "Cargados {{loaded}} de {{total}}. Desplázate para más.", + "endOfResults": "Fin de resultados ({{loaded}} de {{total}})." + }, + "drawer": { + "loading": "Cargando…", + "accuracy": "Precisión:", + "actions": { + "block": "Bloquear en perímetro", + "viewEvents": "Ver eventos coincidentes", + "externalLookup": "Búsqueda externa", + "trackCampaign": "Rastrear campaña", + "viewIocs": "Ver IOCs coincidentes", + "mitre": "MITRE ATT&CK" + }, + "sections": { + "timeline": "Cronología", + "networkOrigin": "Red / origen", + "associationsWithCount": "Asociaciones ({{count}})", + "geolocationsWithCount": "Geolocalizaciones ({{count}})", + "about": "Acerca de", + "activity": "Actividad" + }, + "fields": { + "firstSeen": "Primera vez visto", + "lastSeen": "Última vez visto", + "country": "País", + "city": "Ciudad", + "aso": "ASO", + "asn": "ASN", + "reputation": "Reputación", + "accuracy": "Precisión", + "current": "Actual", + "best": "Mejor", + "worst": "Peor" + }, + "aiBrief": "Resumen IA", + "noDescription": "No hay descripción disponible para este indicador.", + "lastObserved": "Última observación {{when}}." + }, + "actors": { + "empty": "Sin actores encontrados." + }, + "feeds": { + "empty": "Sin feeds configurados.", + "table": { + "name": "Feed", + "type": "Tipo", + "accuracy": "Precisión", + "header": "Fuentes", + "format": "Formato" + }, + "download": "Descargar fuente", + "checksum": "Suma de verificación" + }, + "entityTypes": { + "ip": "IP", + "hostname": "Host", + "domain": "Dominio", + "url": "URL", + "hash": "Hash", + "cve": "CVE", + "threat": "Amenaza", + "entity": "Entidad" + }, + "reputation": { + "alarming": "Alarmante", + "suspicious": "Sospechoso", + "indefinable": "Indefinido", + "fair": "Aceptable", + "trustworthy": "Confiable" + }, + "feedAccuracy": { + "level1": "Nivel 1", + "level2": "Nivel 2", + "level3": "Nivel 3" + }, + "triage": { + "title": "Triage", + "subtitle": "Paste indicators, get verdicts", + "input": "Indicators", + "placeholder": "Paste IPs, domains, URLs or hashes — one per line, or comma separated.\nDefanged values (1.2.3[.]4, hxxp://) are accepted.", + "run": "Triage", + "stop": "Stop", + "reset": "Clear", + "parsed": "{{count}} unique indicators", + "capped": "Capped at {{max}} per run.", + "progress": "{{done}} of {{total}}", + "empty": "Paste indicators above to begin.", + "indicator": "Indicator", + "type": "Type", + "verdict": "Verdict", + "reputation": "Rep", + "accuracy": "Acc", + "tags": "Tags", + "lastSeen": "Last seen", + "exportCsv": "Export CSV", + "exportStix": "Export STIX", + "stixNote": "STIX export includes malicious and suspicious rows only.", + "open": "Open", + "notConfigured": "Threat intelligence is not configured — triage needs an upstream ThreatWinds instance.", + "summary": "Summary", + "v.malicious": "Malicious", + "v.suspicious": "Suspicious", + "v.benign": "Benign", + "v.unknown": "Unknown", + "v.notFound": "Not found", + "v.invalid": "Unrecognised" + }, + "report": { + "title": "Reportar", + "subtitle": "Publicar un indicador en el grafo ThreatWinds", + "submit": "Reportar indicador", + "submitting": "Reportando…", + "error": { + "generic": "No se pudo enviar el indicador. Inténtalo de nuevo." + }, + "value": { + "label": "Indicador", + "placeholder": "IP, dominio, URL, hash o dirección de correo" + }, + "type": { + "label": "Tipo", + "placeholder": "Inferido del valor", + "inferred": "Inferido: {{type}}", + "inferenceFailed": "No se pudo inferir ningún tipo de este valor. Elige uno de la lista o escríbelo.", + "unknown": "«{{type}}» no es un tipo de entidad. Elige uno de la lista." + }, + "tags": { + "label": "Etiquetas", + "placeholder": "phishing, robo-de-credenciales" + }, + "description": { + "label": "Notas" + }, + "reputation": { + "legend": "Reputación", + "hint": "Déjalo sin establecer si no has llegado a un veredicto.", + "alarming": "Alarmante", + "worrying": "Preocupante", + "concerning": "Sospechoso", + "indefinable": "Indefinible", + "adequate": "Adecuado", + "good": "Bueno", + "exceptional": "Excelente" + }, + "associations": { + "legend": "Indicadores relacionados", + "add": "Añadir indicador relacionado", + "remove": "Eliminar", + "valuePlaceholder": "Valor relacionado", + "typePlaceholder": "Tipo (opcional)", + "modeLabel": "Relación", + "mode": { + "association": "Relacionado con", + "aggregation": "Parte de" + }, + "visibilityConflict": "No comparte ningún grupo de visibilidad con el indicador de arriba. Se rechazaría todo el envío." + }, + "attributes": { + "legend": "Detalles", + "hint": "Opcional. Lo que quede en blanco no se envía.", + "invalidHex": "Se esperan {{length}} caracteres hexadecimales.", + "invalidHexAny": "Solo se aceptan caracteres hexadecimales.", + "invalidNumber": "Se espera un número." + }, + "correlate": { + "legend": "Correlacionar", + "hint": "Cada atributo marcado se publica como entidad propia, vinculada a esta.", + "count_one": "Crea {{count}} entidad vinculada.", + "count_other": "Crea {{count}} entidades vinculadas." + }, + "scan": { + "notice": "Reportar esto también encola un análisis del destino." + }, + "receipt": { + "title": "Enviado", + "noVerdict": "Sin veredicto", + "skipped": "No enviado, no se pudo inferir el tipo", + "pending": "Esperando a que el indicador aparezca en el corpus…", + "live": "Activo en el corpus — ver entidad", + "processing": "Siguiendo en proceso de ingestión. Aparecerá cuando el flujo se ponga al día.", + "another": "Reportar otro" + }, + "visibility": { + "legend": "Visible para" + }, + "example": "Probar ejemplo" + } }, - "console": { - "section": "Consola", - "sectionHint": "Ejecuta comandos en este host a través de su agente (respuesta en vivo).", - "open": "Abrir consola", - "close": "Cerrar", - "hint": "Escribe un comando y presiona Enter para ejecutarlo en el agente.", - "running": "Ejecutando…", - "placeholder": "Escribe un comando…", - "offline": "Este agente parece estar offline — puede que no responda a los comandos.", - "vars": { - "button": "Variables", - "title": "Variables de comandos", - "subtitle": "Úsalas en los comandos como", - "add": "Nueva variable", - "name": "Nombre", - "value": "Valor", - "description": "Descripción", - "isSecret": "Secreto (cifrado, enmascarado en la salida)", - "secret": "secreto", - "secretHint": "Déjalo en blanco para mantener el valor guardado.", - "save": "Guardar", - "cancel": "Cancelar", - "edit": "Editar", - "delete": "Eliminar", - "loading": "Cargando…", - "empty": "Aún no hay variables.", - "saved": "Variable guardada", - "deleted": "Variable eliminada", - "nameRequired": "El nombre es obligatorio", - "loadError": "No se pudieron cargar las variables", - "saveError": "No se pudo guardar la variable", - "deleteError": "No se pudo eliminar la variable", - "insert": "Insertar", - "valueRequired": "El valor es obligatorio" - }, - "disabled": "Agente offline — los comandos están deshabilitados", - "connError": "Error de conexión", - "cmdError": "Error de comando", - "shellSelect": "Tipo de shell", - "noRemoteControl": "Este agente se instaló con el control remoto deshabilitado. Rechaza los comandos, y eso solo se cambia en la propia máquina.", - "noRemoteControlShort": "Control remoto deshabilitado en este agente", - "password": { - "title": "Autenticación", - "hint": "Autentifíquese para ejecutar comandos en este agente.", - "tfaPrompt": "Código: ", - "confirm": "OK", + "playground": { + "titleFilter": "Probar pipeline", + "titleRule": "Probar regla", + "noDataTypes": "Este pipeline aún no tiene tipos de datos asignados — añade uno para probarlo.", + "dataTypeLabel": "Tipo de dato", + "dataTypePlaceholder": "No hay tipos de datos disponibles", + "dataTypeSingleHint": "Este pipeline solo tiene un tipo de dato — añade más para poder elegir.", + "rawLogLabel": "Log en crudo", + "rawLogPlaceholder": "Pega una línea de log de ejemplo…", + "rawLogCounter": "{{chars}} caracteres · {{kb}} KB", + "rawLogTooLarge": "Este log supera el límite de 1 MB — recórtalo antes de ejecutar la prueba.", + "run": { + "label": "Ejecutar", + "running": "Probando…", + "waitHint": "Esto puede tardar hasta 15 segundos mientras el pipeline procesa el log." + }, + "errors": { + "busy": "El playground está ocupado con otra prueba — inténtalo de nuevo en un momento.", + "timeout": "La prueba agotó el tiempo — normalmente significa que el tipo de dato seleccionado no coincide con el formato del log.", + "validation": "La solicitud no era válida — revisa el log en crudo y el contenido del pipeline.", + "server": "El playground no pudo completar la prueba — inténtalo de nuevo." + }, + "notices": { + "geo": "El plugin de geolocation no está disponible para esta versión lite del test de filtros y reglas.", + "correlation": "Las reglas que consultan eventos previos mediante las cláusulas afterEvent o correlation requieren que ya existan eventos coincidentes en el sistema para que la alerta bajo prueba se dispare." + }, + "result": { + "label": "Resultado procesado", + "empty": "Ejecuta una prueba para ver aquí el evento procesado.", + "loading": "Esperando el evento procesado…", + "tabs": { + "fields": "Campos", + "json": "JSON" + }, + "fieldsCount_one": "{{count}} campo", + "fieldsCount_other": "{{count}} campos", + "copy": "Copiar", + "copied": "Copiado", + "elapsed": "Procesado en {{time}}", + "elapsedHint": "Tiempo desde Ejecutar hasta el resultado procesado", + "searchPlaceholder": "Buscar campos…", + "noMatch": "Ningún campo coincide con tu búsqueda." + }, + "alerts": { + "label": "Alertas", + "empty": "Ejecuta una prueba para ver aquí las alertas resultantes.", + "none": "No se activó ninguna alerta.", + "count_one": "{{count}} alerta", + "count_other": "{{count}} alertas" + }, + "title": "Test pipeline" + }, + "tenants": { + "title": "Tenants", + "new": "Nuevo tenant", + "subtitle": "Cada cliente que corre en esta instancia, lo que tiene y lo que te deja ver.", + "searchPlaceholder": "Buscar por nombre o dominio…", + "loading": "Cargando tenants…", + "loadFailed": "No se pudieron cargar los tenants.", + "retry": "Reintentar", + "none": "Todavía no hay tenants.", + "noSearchMatch": "Ningún tenant coincide con la búsqueda.", "cancel": "Cancelar", - "authError": "Error de autenticación", - "authHint": "Autentifíquese para ejecutar comandos en este agente.", - "authOk": "Autenticado." - } - }, - "sensitivity": { - "section": "Sensibilidad del activo", - "hint": "Criticidad de negocio (CIA, 0–3) de este activo. Las alertas que apuntan a su host/IP se ponderan con estos valores.", - "saved": "Sensibilidad actualizada", - "failed": "No se pudo actualizar la sensibilidad", - "save": "Guardar", - "confidentiality": "Confidencialidad", - "integrity": "Integridad", - "availability": "Disponibilidad", - "levels": { - "0": "Ninguna", - "1": "Baja", - "2": "Media", - "3": "Alta" - } - }, - "health": { - "online": "en línea", - "offline": "desconectados", - "total": "total" - } - }, - "adversaries": { - "title": "Vista de adversarios", - "subtitle": "Cada IP, host o usuario visto atacando tu entorno, con sus técnicas y objetivos.", - "countChip": "{{count}} adversarios", - "refresh": "Actualizar", - "search": "Buscar por IP, host, usuario, país, ASO…", - "empty": "Ningún adversario coincide.", - "loadError": "No se pudieron cargar los adversarios.", - "retry": "Reintentar", - "views": { - "all": "Todos", - "high": "Severidad alta", - "ip": "IPs", - "host": "Hosts", - "user": "Usuarios" - }, - "threat": { - "critical": "Crítico", - "high": "Alto", - "medium": "Medio", - "low": "Bajo" - }, - "kind": { - "ip": "IP", - "host": "Host", - "user": "Usuario" - }, - "layout": { - "list": "Lista", - "cards": "Tarjetas" - }, - "overview": { - "title": "Actividad de adversarios · últimas 24 horas", - "high": "severidad alta", - "countries": "países", - "alerts": "alertas", - "ago24": "hace 24h", - "ago12": "hace 12h", - "now": "ahora" - }, - "col": { - "adversary": "Adversario", - "threat": "Amenaza", - "alerts": "Alertas", - "targets": "Objetivos", - "lastSeen": "Última vez", - "victims": "Víctimas" - }, - "card": { - "alerts": "Alertas", - "techniques": "Técnicas", - "targets": "Objetivos" - }, - "tabs": { - "profile": "Perfil", - "techniques": "Técnicas", - "targets": "Objetivos", - "alerts": "Alertas" - }, - "drawer": { - "activity": "Actividad en 24 horas", - "identification": "Identificación", - "kindLabel": "Tipo", - "identifier": "Identificador", - "firstSeen": "Visto por primera vez", - "lastSeen": "Última vez", - "geolocation": "Geolocalización", - "country": "País", - "city": "Ciudad", - "topTechniques": "Técnicas principales", - "noTechniques": "Sin técnicas registradas.", - "targets": "Objetivos", - "noTargets": "Sin objetivos registrados.", - "recentAlerts": "Alertas recientes", - "noAlerts": "Sin alertas.", - "echoes": "{{count}} repeticiones" - }, - "relative": { - "justNow": "ahora mismo", - "minutesAgo": "hace {{count}}m", - "hoursAgo": "hace {{count}}h", - "daysAgo": "hace {{count}}d" - }, - "field": { - "ip": "IP", - "host": "Host", - "user": "Usuario", - "port": "Puerto", - "domain": "Dominio", - "mac": "MAC", - "country": "País", - "city": "Ciudad", - "asn": "ASN", - "aso": "ASO" - } - }, - "timeRange": { - "quick": "Rangos rápidos", - "relative": "Relativo", - "absolute": "Absoluto", - "last": "Últimos", - "apply": "Aplicar", - "allTime": "Todo el tiempo", - "from": "Desde", - "to": "Hasta", - "now": "ahora", - "units": { - "minutes": "minutos", - "hours": "horas", - "days": "días", - "weeks": "semanas", - "months": "meses" - }, - "presets": { - "15m": "Últimos 15 minutos", - "1h": "Última hora", - "6h": "Últimas 6 horas", - "24h": "Últimas 24 horas", - "7d": "Últimos 7 días", - "30d": "Últimos 30 días" - } - }, - "socAi": { - "title": "Configuración de SOC-AI", - "subtitle": "Configura el agente de IA que triagea alertas y potencia el asistente de operaciones.", - "section": { - "connection": "Modelo y conexión", - "auth": "Autenticación", - "behavior": "Comportamiento del triage", - "advanced": "Avanzado" - }, - "usage": { - "title": "Uso", - "chat": "Chat completions (hoy)", - "unavailable": "El uso todavía no está disponible.", - "resetsIn": "Se reinicia en {{time}}" - }, - "provider": { - "label": "Proveedor", - "hint": "Define el formato. Cualquiera distinto de Anthropic usa la API compatible con OpenAI." - }, - "model": { - "label": "Modelo", - "hint": "Identificador del modelo del proveedor.", - "customOption": "Modelo personalizado…", - "customPlaceholder": "Ingresa un ID de modelo" - }, - "url": { - "label": "URL de la API", - "hint": "Déjalo vacío para usar el endpoint por defecto del proveedor." - }, - "apiKey": { - "label": "API key", - "hint": "Credencial enviada al proveedor.", - "setHint": "Hay una key guardada. Déjalo en blanco para mantenerla." - }, - "authType": { - "label": "Tipo de autenticación", - "hint": "Cómo se envían las credenciales a tu gateway.", - "options": { - "apiKey": "API Key", - "bearer": "Bearer", - "customHeaders": "Cabeceras personalizadas", - "none": "Ninguna" - } - }, - "authHeaderName": { - "label": "Nombre de cabecera de auth", - "hint": "Cabecera que lleva la key (p.ej. api-key para Azure)." - }, - "authToken": { - "label": "Token Bearer", - "hint": "Credencial enviada al proveedor.", - "setHint": "Hay un token guardado. Déjalo en blanco para mantenerlo." - }, - "customHeaders": { - "label": "Cabeceras personalizadas", - "hint": "Cabeceras extra en cada request. Los valores se cifran; \"*****\" mantiene el guardado.", - "keyPlaceholder": "Nombre de la cabecera", - "valuePlaceholder": "Valor", - "addRow": "Agregar cabecera", - "remove": "Quitar cabecera" - }, - "maxTokens": { - "label": "Máx. tokens", - "hint": "Tokens máximos por respuesta del LLM." - }, - "maxToolIterations": { - "label": "Máx. iteraciones de tools", - "hint": "Tope del bucle planear → tool → observar del agente." - }, - "autoAnalyze": { - "label": "Analizar alertas automáticamente", - "hint": "Triagea las alertas entrantes en tiempo real." - }, - "allowIncidents": { - "label": "Permitir gestionar incidentes", - "hint": "El agente de triage puede crear o actualizar incidentes cuando decide que una alerta lo amerita." - }, - "changeAlertStatus": { - "label": "Cambiar estado de alerta", - "hint": "Permite al agente fijar el estado de una alerta en el triage." - }, - "automaticIncidentCreation": { - "label": "Crear incidentes", - "hint": "Permite al agente abrir incidentes desde alertas triageadas." - }, - "allowedWriteTools": { - "label": "Tools de escritura permitidas", - "hint": "Un nombre de tool MCP por línea que el agente puede usar (p.ej. alerts.update_status). Las notas siempre están permitidas." - }, - "save": "Guardar configuración", - "saving": "Verificando y guardando…", - "saved": "Configuración de SOC-AI guardada", - "saveError": "No se pudo guardar la configuración", - "loadError": "No se pudo cargar la configuración", - "modelRequired": "El modelo es obligatorio", - "applyTags": { - "label": "Aplicar tags", - "hint": "Permite al agente etiquetar alertas durante el triage." - }, - "note": { - "azure": "Pega el endpoint completo de tu deployment de Azure como URL; el modelo es el nombre del deployment. La auth usa la cabecera api-key.", - "ollama": "Apunta la URL a tu host de Ollama. No hace falta API key para una instancia local.", - "custom": "Cualquier endpoint compatible con OpenAI. Define la URL, la auth y las cabeceras extra que necesite tu gateway.", - "threatwinds": "Usa tu licencia de UTMStack automáticamente — no necesita API key. Se factura a través de tu suscripción de ThreatWinds." - }, - "chat": { - "title": "Asistente SOC", - "dashboardCreateTitle": "Creador de paneles", - "empty": "Pregunta lo que quieras sobre tus alertas, detecciones o la consola — puedo investigar y actuar sobre el SIEM.", - "tryPrefix": "Prueba", - "suggestion": "¿cuántas alertas abiertas hay, agrupadas por adversario?", - "placeholder": "Escribe una pregunta…", - "ask": "Preguntar", - "send": "Enviar", - "collapse": "Contraer", - "expand": "Expandir", - "clear": "Limpiar conversación", - "close": "Cerrar", - "copy": "Copiar", - "copied": "Copiado", - "errorGeneric": "Algo salió mal.", - "errorUnreachable": "No se pudo contactar al asistente.", - "compacting": "Compactando contexto…", - "dashboardEditTitle": "Editor de paneles", - "editingDashboard": "Editando: {{name}}", - "soarEditTitle": "Editor de flujos SOAR", - "soarCreateTitle": "Crear flujo SOAR", - "editingFlow": "Editando flujo: {{name}}" - }, - "focus": { - "alert": "Alerta", - "incident": "Incidente", - "remove": "Dejar de compartir con el asistente" - }, - "inheritance": { - "inherited": "Siguiendo la configuración por defecto de la instancia. Si guardas aquí, este tenant pasa a tener la suya.", - "own": "Este tenant tiene su propia configuración.", - "revert": "Volver a la de la instancia", - "reverting": "Volviendo…", - "reverted": "Ahora sigue la configuración de la instancia" - }, - "allowance": { - "title": "Consumo de IA hoy", - "ofLimit": "de {{limit}} peticiones", - "denied": "peticiones — la IA no está disponible para este tenant", - "hint": "Lo fija quien opera la instancia. Se reinicia a medianoche UTC." - } - }, - "alerts": { - "title": "Alertas", - "matching": "{{count}} coincidentes", - "subtitle": "Prioriza lo que importa.", - "openNow": "abiertas ahora mismo.", - "view": { - "alerts": "Alertas", - "overview": "Resumen" - }, - "toolbar": { - "searchPlaceholder": "Buscar por nombre de alerta…", - "allSeverities": "Todas las severidades", - "export": "Exportar CSV", - "refresh": "Actualizar" - }, - "severity": { - "high": "Alta", - "medium": "Media", - "low": "Baja" - }, - "status": { - "open": "Abierta", - "in_review": "En revisión", - "completed": "Completada", - "auto": "Revisión automática" - }, - "statusTabs": { - "all": "Todas" - }, - "overview": { - "overTime": "Alertas en el tiempo", - "matchingAlerts": "alertas coincidentes", - "noData": "Sin datos.", - "bySeverity": "Por severidad", - "byStatus": "Por estado" - }, - "filters": { - "add": "Añadir filtro", - "clearAll": "Limpiar todo", - "filterValues": "Filtrar valores…", - "loadingValues": "Cargando valores…", - "noValues": "No se encontraron valores.", - "pickValue": "Elige un valor para añadir el filtro.", - "empty": "(vacío)", - "cancel": "Cancelar", - "addBtn": "Añadir" - }, - "ops": { - "CONTAIN": "contiene", - "IS": "es", - "IS_NOT": "no es", - "EXIST": "existe", - "DOES_NOT_EXIST": "no existe" - }, - "fields": { - "adversary_domain": "Dominio del adversario", - "adversary_geolocation_asn": "ASN del adversario", - "adversary_geolocation_aso": "ASO del adversario", - "adversary_geolocation_country": "País del adversario", - "adversary_host": "Host del adversario", - "adversary_ip": "IP del adversario", - "adversary_url": "URL del adversario", - "adversary_user": "Usuario del adversario", - "assignee": "Asignado a", - "category": "Categoría", - "dataSource": "Sensor", - "dataType": "Tipo de dato", - "description": "Descripción", - "id": "ID", - "impactScore": "Riesgo", - "impact_availability": "Disponibilidad", - "impact_confidentiality": "Confidencialidad", - "impact_integrity": "Integridad", - "incidentDetail_incidentName": "Nombre del incidente", - "incidentDetail_incidentId": "Id del incidente", - "isIncident": "Es incidente", - "name": "Nombre de la alerta", - "notes": "Notas", - "severity": "Severidad", - "status": "Estado", - "tags": "Etiquetas", - "target_domain": "Dominio del objetivo", - "target_geolocation_asn": "ASN del objetivo", - "target_geolocation_aso": "ASO del objetivo", - "target_geolocation_country": "País del objetivo", - "target_host": "Host del objetivo", - "target_ip": "IP del objetivo", - "target_url": "URL del objetivo", - "target_user": "Usuario del objetivo", - "technique": "Técnica" - }, - "tagFilter": { - "tags": "Etiquetas", - "tag_one": "{{count}} etiqueta", - "tag_other": "{{count}} etiquetas", - "clearSelection": "Limpiar selección", - "noTags": "Sin etiquetas" - }, - "bulk": { - "selected": "{{count}} seleccionadas", - "setStatus": "Cambiar estado", - "addTag": "Añadir etiqueta", - "noTags": "Sin etiquetas", - "addToIncident": "Añadir a incidente", - "clear": "Limpiar" - }, - "tagEditor": { - "tag": "Etiqueta", - "noTagsYet": "Aún no hay etiquetas", - "createTag": "Crear etiqueta", - "newTagName": "Nombre de la etiqueta…", - "createApply": "Crear y aplicar etiqueta", - "save": "Guardar", - "cancel": "Cancelar", - "edit": "Editar etiqueta", - "delete": "Eliminar etiqueta", - "systemLocked": "Etiqueta del sistema (bloqueada)", - "alreadyExists": "Esa etiqueta ya existe.", - "color": "Color {{color}}", - "createRule": "Crear regla de etiquetado con esta etiqueta" - }, - "table": { - "actions": "Acciones", - "alert": "Alerta", - "status": "Estado", - "technique": "Técnica", - "severity": "Severidad", - "risk": "Riesgo", - "echoes": "Ecos", - "time": "Hora", - "riskHint": "Puntuación de riesgo (0–100), coloreada por severidad", - "source": "Origen", - "adversary": "Adversario" - }, - "row": { - "createRuleFromAlert": "Crear una etiqueta a partir de esta alerta", - "createIncident": "Crear incidente a partir de esta alerta", - "viewIncident": "Ver detalles del incidente", - "assignedTo": "Asignado a {{user}}", - "echoesTooltip": "{{count}} ecos — haz clic para expandir", - "echoesEmpty": "Sin ecos registrados" - }, - "echoes": { - "title": "{{count}} ecos", - "close": "Cerrar", - "empty": "No hay ecos registrados para esta alerta.", - "loadError": "No se pudieron cargar los ecos." - }, - "list": { - "loading": "Cargando alertas…", - "loadError": "No se pudieron cargar las alertas.", - "retry": "Reintentar", - "empty": "Ninguna alerta coincide con esta vista." - }, - "badge": { - "incident": "Incidente", - "aiAssessed": "Evaluado por IA" - }, - "drawer": { - "setStatus": "Cambiar estado", - "completeFalsePositive": "Completar + falso positivo", - "addToIncident": "Añadir a incidente", - "partOfIncident": "Parte de un incidente", - "tabs": { - "summary": "Resumen", - "parties": "Partes", - "events": "Eventos", - "history": "Historial" - }, - "section": { - "description": "Descripción", - "solution": "Solución", - "references": "Referencias", - "details": "Detalles", - "yourNotes": "Tus notas", - "notes": "Notas" - }, - "details": { - "severity": "Severidad", - "risk": "Riesgo", - "category": "Categoría", - "technique": "Técnica", - "sensor": "Sensor", - "dataType": "Tipo de dato", - "alertId": "ID de alerta", - "statusNote": "Nota de estado", - "assignee": "Asignado a" - }, - "incidentDetail": { - "incident": "Incidente", - "id": "ID", - "createdBy": "Creado por", - "created": "Creado" - }, - "notesPlaceholder": "Añade notas de investigación…", - "saveNotes": "Guardar notas", - "assignee": "Asignar", - "assign": "Asignar", - "unassign": "Quitar asignación", - "unassigned": "Sin asignar", - "loadingUsers": "Cargando usuarios…", - "observationLabel": "Observación", - "observationPlaceholder": "Añade una observación…", - "cancel": "Cancelar", - "continue": "Continuar" - }, - "related": { - "sample": "Una muestra de hasta ~11 eventos que el motor almacenó en esta alerta. Usa «Ver todos los registros relacionados» para el conjunto completo y sin límite.", - "loadingEchoes": "Cargando los eventos de sus echoes…", - "sampleWithEchoes": "Los eventos guardados en esta alerta y en sus {{count}} echoes ({{read}} leídos). Usa «Ver todos los registros relacionados» para el conjunto completo y sin límite.", - "empty": "No hay eventos de muestra almacenados en esta alerta. Carga el conjunto correlacionado completo en el Explorador de registros.", - "viewAll": "Ver todos los registros relacionados" - }, - "party": { - "source": "Origen / objetivo", - "adversary": "Adversario", - "noData": "Sin datos.", - "ip": "IP", - "host": "Host", - "user": "Usuario", - "domain": "Dominio", - "country": "País" - }, - "history": { - "empty": "Sin historial registrado.", - "by": "por {{user}}", - "actions": { - "UPDATE_STATUS": "Estado actualizado", - "UPDATE_TAGS": "Etiquetas actualizadas", - "UPDATE_NOTES": "Notas actualizadas", - "UPDATE_SOLUTION": "Solución actualizada", - "MARK_AS_INCIDENT": "Marcada como incidente" - }, - "detail": { - "statusTo": "Estado → {{status}}", - "tags": "Etiquetas: {{tags}}", - "aiAdded": "Evaluación de IA añadida", - "observationAdded": "Observación añadida", - "notesUpdated": "Notas actualizadas" - } - }, - "ai": { - "title": "Evaluación de IA del SOC", - "risk": "riesgo {{risk}}", - "score": "{{score}}/100", - "generate": "Generar resumen con IA", - "hint": "SOC-AI investiga esta alerta y añade una evaluación.", - "generating": "Analizando la alerta… puede tardar un minuto.", - "ready": "Resumen de IA listo", - "failed": "No se pudo generar el resumen de IA", - "slow": "El resumen de IA está tardando más de lo esperado. Aparecerá en la alerta cuando esté listo." - }, - "incident": { - "titleAdd_one": "Añadir {{count}} alerta a un incidente", - "titleAdd_other": "Añadir {{count}} alertas a un incidente", - "new": "Nuevo incidente", - "existing": "Incidente existente", - "nameLabel": "Nombre del incidente", - "namePlaceholder": "p. ej. Sospecha de intrusión de Scattered Spider", - "descriptionLabel": "Descripción", - "descriptionPlaceholder": "Resumen opcional…", - "pickLabel": "Elige un incidente", - "loading": "Cargando…", - "selectPlaceholder": "Selecciona un incidente…", - "willLink_one": "Se vinculará {{count}} alerta.", - "willLink_other": "Se vincularán {{count}} alertas.", - "cancel": "Cancelar", - "create": "Crear incidente", - "add": "Añadir a incidente" - }, - "toast": { - "statusUpdated": "Estado actualizado", - "statusFailed": "No se pudo actualizar el estado", - "tagsUpdated": "Etiquetas actualizadas", - "tagsFailed": "No se pudieron actualizar las etiquetas", - "tagCreateFailed": "No se pudo crear la etiqueta", - "tagUpdated": "Etiqueta actualizada", - "tagUpdateFailed": "No se pudo actualizar la etiqueta", - "tagDeleted": "Etiqueta eliminada", - "tagDeleteFailed": "No se pudo eliminar la etiqueta", - "notesSaved": "Notas guardadas", - "notesFailed": "No se pudieron guardar las notas", - "exportFailed": "No se pudo exportar el CSV", - "noRelatedLogs": "No se encontraron registros relacionados con esta alerta", - "relatedLogsFailed": "No se pudieron cargar los registros relacionados", - "incidentCreated": "Incidente creado", - "alertsAdded": "Alertas añadidas al incidente", - "incidentFailed": "No se pudo guardar el incidente", - "assigned": "Alerta asignada", - "unassigned": "Alerta sin asignar", - "assignFailed": "No se pudo actualizar el asignado", - "newAlertsToast_title": "Nuevas alertas", - "newAlertsToast_count_one": "{{count}} nueva alerta", - "newAlertsToast_count_other": "{{count}} nuevas alertas", - "newAlertsToast_view": "Ver" - } - }, - "incidents": { - "title": "Incidentes", - "subtitle": "Agrupa, triajea y resuelve alertas relacionadas como incidentes.", - "refresh": "Actualizar", - "count_one": "{{count}} incidente", - "count_other": "{{count}} incidentes", - "openNow": "abiertos ahora", - "empty": "No hay incidentes que coincidan.", - "loadError": "No se pudieron cargar los incidentes.", - "retry": "Reintentar", - "unassigned": "Sin asignar", - "unknownUser": "Desconocido", - "status": { - "open": "Abierto", - "in_review": "En revisión", - "completed": "Completado", - "merged": "Fusionado" - }, - "sev": { - "high": "Alta", - "medium": "Media", - "low": "Baja", - "unknown": "Sin calificar" - }, - "toolbar": { - "search": "Buscar incidentes…", - "create": "Crear incidente", - "allSeverities": "Todas las severidades", - "export": "Exportar CSV" - }, - "statusTabs": { - "all": "Todos" - }, - "filters": { - "add": "Añadir filtro", - "clearAll": "Limpiar todo", - "filterValues": "Filtrar valores…", - "loadingValues": "Cargando valores…", - "noValues": "No se encontraron valores.", - "pickValue": "Elige un valor para añadir el filtro.", - "empty": "(vacío)", - "cancel": "Cancelar", - "addBtn": "Añadir" - }, - "ops": { - "IS": "es" - }, - "layout": { - "table": "Tabla", - "board": "Tablero" - }, - "table": { - "name": "Incidente", - "status": "Estado", - "severity": "Severidad", - "assignee": "Asignado", - "alerts": "Alertas", - "created": "Creado" - }, - "drawer": { - "created": "Creado {{date}}", - "alertsCount": "{{count}} alertas", - "solutionPlaceholder": "Resolución / notas de remediación…", - "solutionHint": "Se guarda al pasar el incidente a Completado.", - "tabs": { - "overview": "Resumen", - "alerts": "Alertas", - "notes": "Notas", - "history": "Historial" - }, - "section": { - "description": "Descripción", - "solution": "Solución", - "details": "Detalles" - }, - "details": { - "id": "ID", - "status": "Estado", - "severity": "Severidad", - "assignee": "Asignado", - "created": "Creado", - "alerts": "Alertas vinculadas" - } - }, - "alerts": { - "empty": "No hay alertas vinculadas a este incidente.", - "remove": "Desvincular alerta", - "removeConfirm": "¿Desvincular «{{name}}» de este incidente?", - "removed": "Alerta desvinculada", - "removeError": "No se pudo desvincular la alerta", - "loadingAlert": "Cargando alerta…", - "alertGone": "Esta alerta ya no está en el almacén — puede que la retención la haya eliminado.", - "alertFailed": "No se pudo cargar la alerta.", - "openInAlerts": "Abrir en Alertas" - }, - "notes": { - "empty": "Aún no hay notas.", - "add": "Agregar nota", - "addError": "No se pudo agregar la nota", - "placeholder": "Escribe una nota…" - }, - "history": { - "empty": "Aún no hay historial." - }, - "toast": { - "statusChanged": "Estado del incidente actualizado", - "statusError": "No se pudo cambiar el estado", - "exportFailed": "No se pudo exportar el CSV" - }, - "assign": { - "assign": "Asignar", - "search": "Buscar usuarios…", - "unassign": "Quitar asignación", - "noUsers": "Sin usuarios", - "assigned": "Asignado a {{user}}", - "unassigned": "Incidente sin asignar", - "error": "No se pudo cambiar el asignado", - "custom": "Asignar personalizado", - "customPlaceholder": "Escribe un usuario…" - }, - "action": { - "INCIDENT_CREATED": "Incidente creado", - "INCIDENT_ALERT_ADD": "Alertas añadidas", - "INCIDENT_ALERT_STATUS_CHANGED": "Estado de alertas cambiado", - "INCIDENT_STATUS_CHANGE": "Estado cambiado", - "INCIDENT_NOTE_ADD": "Nota añadida", - "INCIDENT_NOTE_CHANGE": "Nota editada", - "INCIDENT_ASSIGNED": "Asignación cambiada" - }, - "create": { - "title": "Crear incidente", - "stepIndicator": "Paso {{current}} de {{total}}", - "selectedCount": "{{count}} alertas seleccionadas", - "submit": "Crear", - "success": "Incidente creado", - "error": "No se pudo crear el incidente", - "details": { - "nameLabel": "Nombre", - "namePlaceholder": "Título corto y descriptivo", - "descriptionLabel": "Descripción", - "descriptionPlaceholder": "Contexto, alcance, notas iniciales…" - } - } - }, - "parsingFilters": { - "title": "Pipelines", - "subtitle": "Pipelines YAML que se aplican a los logs mientras se parsean durante la ingesta.", - "new": "Nuevo pipeline", - "search": "Buscar pipelines…", - "refresh": "Refrescar", - "view": "Ver", - "system": "Sistema", - "user": "Personalizado", - "loading": "Cargando pipelines…", - "loadError": "No se pudieron cargar los pipelines.", - "retry": "Reintentar", - "empty": "Ningún pipeline coincide con esta vista.", - "tabs": { - "all": "Todos", - "active": "Activos", - "inactive": "Inactivos", - "system": "Sistema", - "user": "Personalizados" - }, - "cols": { - "filter": "Pipeline", - "type": "Tipo", - "active": "Activo", - "dataTypes": "Tipos de dato", - "order": "Orden", - "moveUp": "Subir", - "moveDown": "Bajar", - "actions": "Acciones" - }, - "editor": { - "titleNew": "Nuevo pipeline", - "titleEdit": "Editar pipeline", - "titleSystem": "Pipeline (sistema)", - "name": "Nombre", - "namePlaceholder": "Mi pipeline custom", - "nameHint": "Se guardará como {{file}}", - "namePending": "Elige un nombre — será el nombre del archivo.", - "content": "Contenido (pipeline YAML)", - "contentHint": "Una definición válida en pipeline: YAML.", - "readOnly": "Pipeline de sistema — solo lectura. Solo puedes activarlo o desactivarlo.", - "save": "Guardar", - "saving": "Guardando…", - "delete": "Eliminar", - "confirmDelete": "Confirmar eliminación", - "cancel": "Cancelar", - "test": "Test" - }, - "toast": { - "saved": "Pipeline guardado", - "saveError": "No se pudo guardar el pipeline", - "deleted": "Pipeline eliminado", - "deleteError": "No se pudo eliminar el pipeline", - "activateError": "No se pudo cambiar el estado del pipeline", - "nameRequired": "El nombre es obligatorio", - "contentRequired": "El contenido es obligatorio", - "orderError": "No se pudo cambiar el orden del pipeline" - }, - "visual": { - "visualTab": "Visual", - "codeTab": "Código", - "codeOnly": "Cambia a Código — este contenido no se puede mostrar de forma visual.", - "cantParse": "No se puede abrir el editor visual: {{error}}", - "dataTypes": "Tipos de dato", - "steps": "Pasos", - "noSteps": "Aún no hay pasos.", - "addStep": "Agregar paso:", - "removeStep": "Eliminar paso", - "moveUp": "Subir", - "moveDown": "Bajar", - "whereHint": "condición opcional (CEL)", - "addValue": "Agregar valor", - "addPattern": "Agregar patrón", - "rawHint": "Este procesador se edita como YAML directo.", - "rawNotMap": "Debe ser un conjunto de campos clave: valor.", - "dataTypesPick": "Elegir tipos de dato", - "dataTypesSearch": "Buscar tipos de dato…", - "dataTypesNone": "Sin tipos de dato", - "dataTypesAdd": "Agregar \"{{value}}\"", - "insertPattern": "Insertar patrón regex", - "patternSearch": "Buscar patrones…", - "patternNone": "Sin patrones", - "newPattern": "Nuevo patrón…", - "createInsert": "Crear e insertar", - "patternCreated": "Patrón \"{{name}}\" creado", - "patternCreateError": "No se pudo crear el patrón", - "patternIdInvalid": "El ID debe empezar con letra o _ y usar solo letras, dígitos o _", - "patternDefRequired": "La definición es obligatoria", - "parameters": "Parámetros", - "paramsKey": "Clave", - "paramsValue": "Valor", - "entry": "Entrada {{n}}", - "order": "orden {{n}}", - "orderLabel": "Orden", - "removeEntry": "Eliminar entrada", - "addEntry": "Añadir entrada de pipeline", - "collapse": "Contraer", - "expand": "Expandir", - "splitHint": "Vacío equivale a un espacio por defecto — en el YAML siempre aparece como fieldSplit: \" \"." - }, - "allDataTypes": "Todos los tipos de dato", - "testPipeline": "Test pipeline" - }, - "alertingRules": { - "title": "Reglas de Alertas", - "subtitle": "Reglas de correlación que convierten eventos en alertas. Actívalas, ajústalas o crea las tuyas.", - "new": "Nueva regla", - "refresh": "Actualizar", - "empty": "No hay reglas que coincidan.", - "loadError": "No se pudieron cargar las reglas.", - "retry": "Reintentar", - "deleteConfirm": "¿Eliminar la regla «{{name}}»?", - "adversary": { - "origin": "Origen", - "target": "Destino" - }, - "state": { - "active": "Activa", - "inactive": "Inactiva" - }, - "owner": { - "system": "Sistema", - "custom": "Personalizada" - }, - "toolbar": { - "search": "Buscar reglas…", - "allCategories": "Todas las categorías", - "allAdversaries": "Todos los adversarios", - "allStates": "Todos los estados", - "allOwners": "Todos los orígenes", - "allDataTypes": "Todos los tipos" - }, - "table": { - "name": "Regla", - "category": "Categoría", - "technique": "Técnica", - "adversary": "Adversario", - "impact": "Impacto", - "active": "Activa", - "dataTypes": "Tipos de dato", - "selectAll": "Seleccionar todo", - "selectRow": "Seleccionar {{name}}" - }, - "export": { - "all": "Exportar todo", - "selected": "Exportar ({{count}})", - "error": "No se pudieron exportar las reglas" - }, - "view": { - "description": "Descripción", - "details": "Detalles", - "impact": "Impacto (C·I·D)", - "dataTypes": "Tipos de dato", - "updated": "Actualizada", - "relPath": "Ruta", - "definition": "Condición (CEL)", - "correlationSteps": "Pasos de correlación", - "correlation": "Correlación", - "groupBy": "Agrupar por", - "deduplicateBy": "Deduplicar por", - "references": "Referencias" - }, - "editor": { - "createTitle": "Nueva regla", - "edit": "Editar", - "delete": "Eliminar", - "export": "Exportar", - "cancel": "Cancelar", - "save": "Guardar", - "metadata": "Metadatos", - "name": "Nombre", - "confidentiality": "Confidencialidad", - "integrity": "Integridad", - "availability": "Disponibilidad", - "dataTypes": "Tipos de dato", - "dataTypesHint": "separados por coma", - "activeOnSave": "Activa", - "definitionSection": "Definición", - "where": "Condición (CEL)", - "whereHint": "Expresión CEL evaluada por evento", - "correlationSteps": "Pasos de correlación", - "correlationStepsHint": "array JSON", - "jsonArray": "array JSON", - "nameRequired": "El nombre es obligatorio", - "definitionRequired": "La condición es obligatoria", - "invalidJson": "Un campo de la definición tiene JSON inválido", - "addStep": "Agregar paso de correlación", - "step": "Paso {{n}}", - "removeStep": "Quitar paso", - "indexPattern": "Patrón de índice", - "within": "Ventana", - "count": "Cantidad", - "conditions": "Condiciones", - "field": "Campo", - "value": "Valor", - "addCondition": "Agregar condición", - "orGroup": "Grupo Or {{n}}", - "addOr": "Agregar grupo Or", - "removeOr": "Quitar", - "fieldsHint": "nombres de campo", - "referencesHint": "URLs", - "visual": "Visual", - "code": "Código", - "dataTypesPick": "Seleccionar…", - "dataTypesSearch": "Buscar tipos de dato…", - "dataTypesNone": "Sin tipos de dato", - "visualTab": "Visual", - "codeTab": "Código", - "yamlError": "No se puede aplicar el YAML: {{error}}", - "test": "Test" - }, - "toast": { - "activated": "Regla activada", - "deactivated": "Regla desactivada", - "toggleError": "No se pudo cambiar el estado de la regla", - "deleted": "Regla eliminada", - "deleteError": "No se pudo eliminar la regla", - "created": "Regla creada", - "saved": "Regla guardada", - "saveError": "No se pudo guardar la regla" - }, - "operator": { - "filter_term": "igual (term)", - "must_not_term": "distinto (term)", - "filter_match": "coincide (texto)", - "must_not_match": "no coincide (texto)" - }, - "where": { - "matchPrefix": "Coincide con", - "all": "todas", - "any": "cualquiera", - "matchSuffix": "de estas condiciones:", - "negate": "Negar", - "listHint": "separado por comas", - "advanced": "Esta condición usa CEL avanzado — edítala en Código o reconstrúyela visualmente.", - "and": "Y", - "or": "O" - }, - "celOp": { - "exists": "existe", - "equals": "igual a", - "equalsIgnoreCase": "igual (sin may.)", - "contains": "contiene", - "oneOf": "es uno de", - "containsAll": "contiene todos", - "startsWith": "empieza con", - "endsWith": "termina con", - "regexMatch": "regex", - "lessThan": "<", - "lessOrEqual": "≤", - "greaterThan": ">", - "greaterOrEqual": "≥", - "inCIDR": "en CIDR", - "isHour": "la hora es", - "isMinute": "el minuto es", - "isDayOfWeek": "el día es", - "isWeekend": "es fin de semana", - "isWorkDay": "es día hábil", - "isBetweenTime": "hora entre" - }, - "import": { - "button": "Importar", - "error": "Falló la importación", - "resultTitle": "Resultados de la importación", - "approved": "Aprobadas", - "rejected": "Rechazadas", - "done": "Listo" - }, - "test": "Test" - }, - "regexPatterns": { - "title": "Expresiones regulares", - "subtitle": "Expresiones regulares reutilizables referenciadas por los filtros de parseo.", - "new": "Nuevo patrón", - "search": "Buscar patrones…", - "refresh": "Actualizar", - "view": "Ver", - "system": "Sistema", - "user": "Personalizado", - "loading": "Cargando patrones…", - "loadError": "No se pudieron cargar los patrones.", - "retry": "Reintentar", - "empty": "Ningún patrón coincide con esta vista.", - "tabs": { - "all": "Todos", - "system": "Sistema", - "user": "Personalizados" - }, - "cols": { - "pattern": "Patrón", - "definition": "Definición", - "type": "Tipo" - }, - "editor": { - "titleNew": "Nuevo patrón", - "patternId": "ID del patrón", - "patternIdHint": "Nombre único referenciado desde los filtros.", - "description": "Descripción", - "descriptionPlaceholder": "Qué reconoce este patrón (opcional)", - "definition": "Definición (regex)", - "definitionHint": "Una expresión regular. Puede referenciar otros patrones.", - "readOnly": "Patrón de sistema — solo lectura.", - "save": "Guardar", - "saving": "Guardando…", - "delete": "Eliminar", - "confirmDelete": "Confirmar eliminación", - "cancel": "Cancelar" - }, - "toast": { - "saved": "Patrón guardado", - "saveError": "No se pudo guardar el patrón", - "deleted": "Patrón eliminado", - "deleteError": "No se pudo eliminar el patrón", - "patternIdRequired": "El ID del patrón es obligatorio", - "definitionRequired": "La definición es obligatoria" - } - }, - "soar": { - "title": "SOAR", - "subtitle": "Flujos de respuesta automática: las condiciones coinciden con una alerta y los comandos corren en el agente.", - "comingSoon": "Próximamente", - "console": { - "loading": "Cargando agentes…", - "loadError": "No se pudieron cargar los agentes.", - "pickAgent": "Selecciona un agente", - "pickAgentHint": "Elige un agente de la lista para abrir su consola interactiva.", - "lockedAgent": "Control remoto deshabilitado" - }, - "search": "Buscar flujos…", - "refresh": "Refrescar", - "new": "Nuevo flujo", - "view": "Ver", - "system": "Sistema", - "loading": "Cargando flujos…", - "loadError": "No se pudieron cargar los flujos.", - "retry": "Reintentar", - "empty": "Ningún flujo coincide con esta vista.", - "templates": { - "title": "Nuevo flujo", - "subtitle": "Elige una plantilla de acción o empieza desde cero.", - "loading": "Cargando plantillas…", - "loadError": "No se pudieron cargar las plantillas.", - "empty": "No hay plantillas disponibles.", - "cancel": "Cancelar", - "scratch": "Empezar desde cero" - }, - "tabs": { - "flows": "Flujos", - "executions": "Historial de ejecuciones", - "all": "Todos", - "active": "Activos", - "inactive": "Inactivos", - "system": "Sistema", - "user": "Propios" - }, - "cols": { - "flow": "Flujo", - "platform": "Plataforma", - "conditions": "Condiciones", - "commands": "Comandos", - "active": "Activo", - "lastRun": "Última ejecución", - "failedRuns_one": "{{count}} ejecución fallida", - "failedRuns_other": "{{count}} ejecuciones fallidas" - }, - "operator": { - "IS": "es", - "IS_NOT": "no es", - "CONTAINS": "contiene", - "NOT_CONTAINS": "no contiene", - "EXISTS": "existe", - "NOT_EXISTS": "no existe", - "START_WITH": "comienza con", - "NOT_START_WITH": "no comienza con", - "ENDS_WITH": "termina con", - "NOT_ENDS_WITH": "no termina con", - "IS_ONE_OF": "es uno de", - "IS_NOT_ONE_OF": "no es uno de" - }, - "toast": { - "created": "Flujo creado", - "saved": "Flujo guardado", - "saveError": "No se pudo guardar el flujo", - "deleted": "Flujo eliminado", - "deleteError": "No se pudo eliminar el flujo", - "activateError": "No se pudo cambiar el estado del flujo" - }, - "editor": { - "createTitle": "Nuevo flujo", - "visualTab": "Visual", - "codeTab": "Código", - "name": "Nombre", - "description": "Descripción", - "conditions": "Condiciones", - "conditionsHint": "El flujo corre cuando una alerta cumple TODAS estas condiciones.", - "field": "campo", - "value": "valor", - "valueList": "valores separados por coma", - "addCondition": "Agregar condición", - "commands": "Comandos", - "commandsHint": "Se ejecutan en orden en el agente. Usa $(field.path) para valores de la alerta y $[variables.NAME] para variables guardadas.", - "addCommand": "Agregar comando", - "templatesButton": "Comandos comunes", - "templates": { - "isolate": "Aislar de la red", - "shutdown": "Apagar máquina", - "killProcess": "Matar proceso", - "logout": "Cerrar sesión", - "disableUser": "Deshabilitar usuario", - "blockIp": "Bloquear IP", - "restart": "Reiniciar la máquina", - "uninstall": "Desinstalar aplicación" - }, - "connector": { - "always": "siempre", - "success": "si tuvo éxito", - "failure": "si falló" - }, - "agentPlatform": "Plataforma del agente", - "shell": "Shell", - "shellAuto": "auto", - "whereToRun": "Dónde ejecutar", - "run": { - "all": "Todos los agentes", - "specific": "Un agente", - "except": "Todos excepto", - "allHint": "Se ejecuta en todos los agentes que coincidan con esta plataforma." - }, - "selectAgentPlaceholder": "Selecciona un agente…", - "excludedAgentsHint": "escribe un hostname y presiona Enter", - "save": "Guardar", - "delete": "Eliminar", - "confirmDelete": "Confirmar eliminación", - "cancel": "Cancelar", - "yamlError": "No se puede aplicar el YAML: {{error}}", - "nameRequired": "El nombre es obligatorio", - "conditionsRequired": "Se requiere al menos una condición con campo", - "commandsRequired": "Se requiere al menos un comando", - "httpUrlInvalid": "El nodo HTTP \"{{id}}\" tiene una URL inválida — debe ser una URL http(s) válida.", - "httpBodyInvalid": "El cuerpo del nodo HTTP \"{{id}}\" no es JSON válido: {{error}}", - "incidentNameRequired": "El nodo de incidente \"{{id}}\" requiere un nombre.", - "mailToRequired": "El nodo de correo \"{{id}}\" requiere al menos un destinatario.", - "mailAddressInvalid": "El nodo de correo \"{{id}}\" tiene una dirección {{field}} no válida: {{address}}.", - "mailSubjectRequired": "El nodo de correo \"{{id}}\" requiere un asunto.", - "identityModalTitle": "Detalles del flujo", - "platformRequired": "La plataforma del agente es obligatoria", - "nameLabel": "Nombre", - "namePlaceholder": "Nombre del flujo", - "descriptionLabel": "Descripción", - "descriptionHint": "¿Qué hace este flujo? (opcional)", - "when": "Cuando", - "whenTitle": "Una alerta cumple todas estas condiciones", - "on": "En", - "onTitle": "El agente que coincide", - "thenRun": "Entonces ejecuta", - "thenTitle": "Estos comandos, en orden", - "selectField": "Elegir un campo…", - "selectPlatform": "Elegir una plataforma…", - "searchAgents": "Buscar agentes…", - "noAgents": "Sin agentes", - "insertInto": "Insertar en el comando {{n}}:", - "insertField": "Campo de alerta", - "variables": "Variables", - "canvas": { - "node": "Nodo", - "deleteNode": "Eliminar nodo", - "id": "ID", - "kind": "Tipo", - "executor": "Ejecutor", - "commandLabel": "Comando", - "paramsJson": "Parámetros (JSON)", - "dragToResize": "Arrastra para redimensionar", - "templatesLabel": "Plantillas", - "templatesNeedPlatform": "Selecciona primero la plataforma destino", - "handlesHint": "Arrastra desde el conector verde (abajo-izquierda) para on_success y desde el rojo (abajo-derecha) para on_error. Varias conexiones = paralelo. Varias conexiones a un mismo nodo = AND-join.", - "invalidJson": "JSON inválido", - "hidePalette": "Ocultar paleta", - "hideInspector": "Ocultar inspector", - "paletteLabel": "Paleta", - "nodeShort": "Nodo", - "showPanel": "Mostrar {{name}}", - "platform": "Plataforma", - "shell": "Shell", - "any": "cualquiera", - "auto": "auto", - "runOn": "Ejecutar en", - "runAutoTitle": "Se ejecuta en el host que generó la alerta", - "runSpecificTitle": "Fijar a un host (o una plantilla como $(alert.foo))", - "runExceptTitle": "Se ejecuta en el host que generó la alerta, excluyendo los de la lista", - "runAutoLabel": "fuente de alerta", - "runSpecificLabel": "un host", - "runExceptLabel": "todos excepto", - "runAutoHint": "Se ejecuta en $(alert.dataSource) — el host que generó la alerta.", - "pickHost": "elige un host…", - "orTemplateHint": "O escribe una plantilla — $(alert.field) se resuelve en cada ejecución.", - "addExclusion": "añadir exclusión", - "searchAgents": "buscar agentes…", - "noAgents": "sin agentes", - "insertField": "Insertar campo", - "alert": "Alerta", - "wholeOutput": "salida completa (edita la ruta)", - "noAncestorsHint": "Aún no hay ancestros de enriquecimiento — añade un nodo de enriquecimiento previo para exponer su salida aquí.", - "inserts": "inserta", - "conditionalHint": "Todas las condiciones deben coincidir. Coincidencia → rama de éxito (verde); fallo → rama de error (rojo).", - "http": { - "url": "URL", - "urlInvalid": "URL http(s) inválida.", - "method": "Método", - "body": "Cuerpo (JSON)", - "bodyInvalid": "JSON inválido", - "headers": "Encabezados HTTP", - "params": "Parámetros de consulta", - "key": "Clave", - "value": "Valor", - "addHeader": "Agregar encabezado", - "addParam": "Agregar parámetro" + "saving": "Guardando…", + "chips": { + "total": "tenants", + "active": "activos", + "readable": "con acceso" }, - "incident": { - "name": "Nombre del incidente", - "namePlaceholder": "Ej. Inicio de sesión sospechoso en $(alert.dataSource)", - "description": "Descripción", - "descriptionPlaceholder": "Contexto opcional para los responsables. Plantillas como $(alert.name) se interpolan." - }, - "llm": { - "prompt": "Prompt", - "hint": "El modelo siempre responde con un único objeto JSON que incluye la propiedad \"result\"; el backend garantiza ese formato aunque el modelo se desvíe. Los nodos hijos la consultan con $({{nodeId}}.result) o campos específicos." - }, - "mail": { - "to": "Para (separados por coma)", - "cc": "CC (separados por coma, opcional)", - "addressInvalid": "Dirección de correo no válida: {{address}}", - "subject": "Asunto", - "subjectPlaceholder": "Ej. Alerta en $(alert.dataSource)", - "body": "Cuerpo", - "bodyPlaceholder": "Contenido del mensaje. Plantillas como $(alert.name) se interpolan." - }, - "notify": { - "level": "Level", - "message": "Message", - "messagePlaceholder": "Notification text. Templates like $(alert.name) are interpolated." + "status": { + "ACTIVE": "Activo", + "SUSPENDED": "Suspendido", + "TERMINATED": "Terminado" + }, + "support": { + "NONE": "Sin acceso", + "READ": "Acceso de lectura", + "FULL": "Acceso total", + "hint": "Lo concede el tenant, no tú. Solo su administrador puede cambiarlo." + }, + "card": { + "edit": "Editar", + "activate": "Activar", + "deactivate": "Desactivar", + "deletePermanent": "Eliminar permanentemente", + "noAccess": "Este tenant no te ha dado acceso.", + "loadingStats": "Leyendo…", + "enter": "Entrar" + }, + "stats": { + "users": "Usuarios", + "datasources": "Fuentes", + "openAlerts": "Alertas abiertas", + "ai": "IA hoy", + "noLimit": "sin tope" + }, + "fields": { + "name": "Nombre", + "domain": "Dominio", + "domainHint": "Por dónde se llega a este tenant. Toda petición a ese host entra en sus datos.", + "adminEmail": "Correo del administrador", + "adminEmailHint": "Recibe una invitación para poner su propia contraseña.", + "status": "Estado", + "suspendedWarning": "Un tenant suspendido no puede iniciar sesión. Sus datos se conservan.", + "aiLimit": "Tope de peticiones de IA", + "aiLimitHint": "Un tope operativo, por día. Sin tope, gastan contra la licencia de la instancia.", + "aiLimitToggle": "Poner tope a este tenant" + }, + "create": { + "title": "Nuevo tenant", + "subtitle": "Crea el tenant e invita a su primer administrador.", + "submit": "Crear tenant" + }, + "edit": { + "title": "Editar tenant", + "subtitle": "El acceso de soporte no está aquí: solo el tenant puede concederlo.", + "submit": "Guardar cambios" + }, + "terminate": { + "title": "¿Desactivar este tenant?", + "body": "Nadie de {{name}} podrá iniciar sesión. Sus datos se conservan, así que es reversible, pero deja al cliente fuera ahora mismo.", + "confirmLabel": "Escribe {{name}} para confirmar", + "submit": "Desactivar" + }, + "reactivate": { + "title": "¿Activar este tenant?", + "body": "{{name}} podrá iniciar sesión de nuevo. Sus datos conservados se restauran tal cual.", + "submit": "Activar" + }, + "deletePermanent": { + "title": "¿Eliminar este tenant para siempre?", + "body": "Todo rastro de {{name}} — usuarios, fuentes de datos, dashboards, alertas, integraciones — será borrado. Esto no se puede deshacer.", + "confirmLabel": "Escribe {{name}} para confirmar", + "submit": "Eliminar para siempre" + }, + "toast": { + "created": "Tenant creado", + "updated": "Tenant actualizado", + "terminated": "Tenant terminado", + "reactivated": "Tenant reactivado", + "permanentlyDeleted": "Tenant eliminado permanentemente", + "domainInUse": "Ese dominio ya está en uso", + "noPermission": "No tienes permiso para hacer eso", + "notFound": "Tenant no encontrado", + "invalidRequest": "Petición inválida", + "operationFailed": "La operación falló" + }, + "switcher": { + "aria": "Switch tenant", + "self": "Default tenant", + "create": "Create tenant" } - } - }, - "executions": { - "search": "Buscar por ID de alerta…", - "all": "Todas", - "loading": "Cargando ejecuciones…", - "loadError": "No se pudieron cargar las ejecuciones.", - "retry": "Reintentar", - "empty": "Aún no hay ejecuciones.", - "cols": { - "status": "Estado", - "flow": "Flujo", - "command": "Comando / Acción", - "agent": "Agente", - "date": "Fecha", - "retries": "Reintentos", - "node": "Nodo" - }, - "filters": { - "source": "Origen", - "allSources": "Todos los orígenes" - }, - "manual": "Consola interactiva" - }, - "executionStatus": { - "WAITING": "En espera", - "PENDING": "Pendiente", - "EXECUTING": "Ejecutando", - "EXECUTED": "Ejecutado", - "FAILED": "Fallido", - "DEAD": "Inaccesible" - }, - "executionOrigin": { - "FLOW": "Flujo", - "MANUAL": "Manual" - }, - "nonExecutionCause": { - "AGENT_OFFLINE": "Agente offline", - "AGENT_NOT_FOUND": "Agente no encontrado", - "UNKNOWN": "Desconocido" - }, - "kpi": { - "flows": "Flujos totales", - "active": "Activos", - "runs24h": "Ejecuciones (24h)", - "failed24h": "Fallidas (24h)" - }, - "neverRun": "nunca", - "create": { - "title": "Nuevo flujo", - "modeManual": "Crear manualmente", - "modeAi": "Con IA", - "aiLocked": "Active SOC-AI y configúrelo para usar esto.", - "name": "Nombre del flujo", - "namePlaceholder": "p. ej. Bloquear IP por fallos repetidos", - "aiDescriptionLabel": "¿Qué debe hacer este flujo?", - "aiDescriptionPlaceholder": "p. ej. Ante una alerta crítica, buscar la IP de origen en inteligencia de amenazas y bloquearla en el firewall", - "aiCreate": "Crear con IA", - "manualContinue": "Continuar" - } - }, - "compliance": { - "title": "Compliance", - "subtitle": "Evalúa tu postura frente a frameworks de seguridad — mira qué controles se cumplen y cuáles no.", - "comingSoon": "Próximamente.", - "tabs": { - "frameworks": "Frameworks", - "schedule": "Programación", - "controls": "Controles" - }, - "search": "Buscar frameworks…", - "refresh": "Actualizar", - "loading": "Cargando frameworks…", - "loadError": "No se pudieron cargar los informes", - "retry": "Reintentar", - "empty": "Ningún framework coincide.", - "notEvaluated": "Sin evaluar", - "controlsCount": "{{n}} controles", - "enabledLabel": "Activo", - "runReport": "Correr reporte", - "backToFrameworks": "Volver a frameworks", - "statusAuto": "Auto (evaluado)", - "overrideError": "No se pudo actualizar el estado", - "noteError": "No se pudo guardar la nota", - "notes": { - "title": "Notas", - "placeholder": "Agregar una nota…", - "save": "Guardar", - "cancel": "Cancelar" - }, - "reasonModal": { - "title": "Motivo requerido", - "description": "Indica el motivo del cambio de estado. Se registrará.", - "label": "Motivo", - "placeholder": "Explica por qué cambias el estado de este control…", - "confirm": "Confirmar cambio", - "cancel": "Cancelar" - }, - "coverageLabel": "Cobertura", - "activityLabel": "Actividad", - "evidenceLabel": "Evidencia", - "seeMore": "Ver más", - "seeLess": "Ver menos", - "evaluating": "Evaluando framework…", - "complianceScore": "Puntaje de compliance", - "generatedAt": "Generado {{date}}", - "reportError": "No se pudo generar el reporte.", - "coverage": "{{n}} reglas", - "activity": "{{n}} alertas", - "status": { - "COMPLIANT": "Cumple", - "NON_COMPLIANT": "No cumple", - "AT_RISK": "En riesgo", - "NOT_COVERED": "Sin cobertura", - "OUT_OF_SCOPE": "Fuera de alcance", - "PENDING": "Pendiente", - "label": "Estado", - "NOT_EVALUATED": "Sin evaluar" - }, - "toast": { - "toggleError": "No se pudo cambiar el estado del framework", - "reportGenerated": "Reporte generado", - "reportError": "No se pudo generar el reporte" - }, - "schedule": { - "new": "Nueva programación", - "loading": "Cargando programaciones…", - "loadError": "No se pudieron cargar las programaciones.", - "empty": "Aún no hay programaciones.", - "edit": "Editar", - "delete": "Eliminar", - "newTitle": "Nueva programación", - "editTitle": "Editar programación", - "framework": "Framework", - "cadenceLabel": "Cadencia", - "cronHint": "Cron de 5 campos (min hora día mes díaSemana).", - "recipientsHint": "Emails separados por coma. Vacío = solo guarda el snapshot.", - "save": "Guardar", - "cancel": "Cancelar", - "frameworkRequired": "El framework es obligatorio", - "cronRequired": "La programación (cron) es obligatoria", - "cadence": { - "daily": "Diaria", - "weekly": "Semanal", - "monthly": "Mensual", - "custom": "Personalizada" - }, - "toast": { - "saved": "Programación guardada", - "saveError": "No se pudo guardar la programación", - "deleted": "Programación eliminada", - "deleteError": "No se pudo eliminar la programación" - }, - "to": "Para", - "cc": "Cc", - "toRequired": "Se requiere al menos un destinatario", - "windowDays": "Ventana del informe (días)", - "windowDaysShort": "sobre {{days}}d", - "windowDaysHint": "Cuánto abarca el informe. Independiente de cada cuánto se ejecuta." - }, - "frameworks": { - "new": "Nuevo framework", - "edit": "Editar", - "createTitle": "Nuevo framework", - "visualTab": "Visual", - "codeTab": "Código", - "key": "Clave", - "name": "Nombre", - "description": "Descripción", - "source": "Fuente", - "sections": "Secciones", - "sectionKey": "clave de sección", - "sectionName": "Nombre de sección", - "requirements": "Requisitos", - "reqId": "id req", - "reqName": "Nombre del requisito", - "addSection": "Agregar sección", - "addRequirement": "Agregar requisito", - "satisfiedBy": "satisfecho por controles", - "searchControls": "Buscar controles…", - "noControls": "Sin controles", - "save": "Guardar", - "delete": "Eliminar", - "confirmDelete": "Confirmar eliminación", - "cancel": "Cancelar", - "yamlError": "No se puede aplicar el YAML: {{error}}", - "keyRequired": "La clave es obligatoria", - "nameRequired": "El nombre es obligatorio", - "toast": { - "created": "Framework creado", - "saved": "Framework guardado", - "saveError": "No se pudo guardar el framework", - "deleted": "Framework eliminado", - "deleteError": "No se pudo eliminar el framework" - }, - "createControl": "Crear nuevo control…", - "createNamed": "Crear control \"{{name}}\"…" - }, - "controls": { - "search": "Buscar controles…", - "allFamilies": "Todas las familias", - "new": "Nuevo control", - "loading": "Cargando controles…", - "loadError": "No se pudieron cargar los controles.", - "empty": "Ningún control coincide.", - "showingOf": "Mostrando {{shown}} de {{total}}", - "id": "ID", - "name": "Nombre", - "family": "Familia", - "familyName": "Familia", - "scope": "Alcance", - "source": "Fuente", - "notInLibrary": "Control no encontrado en la biblioteca", - "scopeOpt": { - "data": "Datos", - "governance": "Gobernanza" - }, - "strategy": "Estrategia", - "statement": "Enunciado", - "remediation": "Remediación", - "checks": "Checks", - "checksHint": "Cada check corre una consulta SQL en OpenSearch y aplica una regla para decidir pasa/falla.", - "checkKey": "clave", - "checkName": "Nombre del check", - "rule": { - "MIN_HITS_REQUIRED": "Mín hits requeridos", - "THRESHOLD_MAX": "Umbral máx" - }, - "ruleNone": "Sin regla", - "ruleValue": "valor", - "addCheck": "Agregar check", - "createTitle": "Nuevo control", - "visualTab": "Visual", - "codeTab": "Código", - "save": "Guardar", - "delete": "Eliminar", - "confirmDelete": "Confirmar eliminación", - "cancel": "Cancelar", - "yamlError": "No se puede aplicar el YAML: {{error}}", - "idRequired": "El ID es obligatorio", - "nameRequired": "El nombre es obligatorio", - "anyDataType": "Cualquier tipo de dato", - "addFilter": "Añadir filtro", - "filterField": "log.eventCode", - "filterValue": "valor", - "filterValues": "a, b, c", - "toast": { - "created": "Control creado", - "saved": "Control guardado", - "saveError": "No se pudo guardar el control", - "deleted": "Control eliminado", - "deleteError": "No se pudo eliminar el control" - } - }, - "doc": { - "title": "Reporte de Compliance", - "print": "Imprimir / PDF", - "controlsEvaluated": "{{n}} controles evaluados", - "executiveSummary": "Resumen Ejecutivo", - "bySection": "Hallazgos por Sección", - "footer": "{{framework}} — Reporte de compliance generado {{date}} · {{brand}}", - "download": "Descargar PDF", - "downloadError": "No se pudo descargar el PDF", - "error": "No se pudo generar el PDF", - "building": "Generando el documento…" - }, - "locked": { - "badge": "Enterprise", - "upgrade": "Pasar a Enterprise", - "upsell": "Este framework/control requiere la edición Enterprise." - }, - "run": "Ejecutar evaluación", - "runError": "La evaluación falló", - "noReportYet": "Este framework aún no se ha evaluado.", - "window": "ventana {{from}} → {{to}}", - "scoredOver": "{{compliant}} de {{evaluated}} requisitos cumplidos · {{total}} en el framework", - "editStale": "Registrado cuando el motor decía {{was}}; ahora dice {{now}}", - "checkResults": "Resultados de los checks", - "verdict": "Veredicto registrado", - "engineSaid": "el motor decía", - "hits": "coincidencias", - "noDataFor": "sin datos de {{dataType}} en la ventana", - "setStatus": "Cambiar estado", - "outcome": { - "PASSED": "Pasó", - "FAILED": "Falló", - "NOT_APPLICABLE": "Sin datos", - "ERROR": "Error" - }, - "system": "Del sistema", - "addNote": "Añadir nota", - "noteModal": { - "title": "Nota", - "description": "Se guarda en el informe. No cambia el estado del control.", - "placeholder": "Remediación en curso — ticket OPS-4412, cierre fin de trimestre." - }, - "history": { - "title": "Score en el tiempo", - "score": "Score de cumplimiento", - "coverage": "Evaluados", - "error": "No se pudo cargar el histórico" - } - }, - "taggingRules": { - "title": "Reglas de etiquetado", - "subtitle": "Etiqueta automáticamente las alertas que cumplan las condiciones.", - "new": "Nueva regla", - "refresh": "Actualizar", - "empty": "Aún no hay reglas de etiquetado.", - "loadError": "No se pudieron cargar las reglas de etiquetado.", - "retry": "Reintentar", - "deleteConfirm": "¿Eliminar la regla \"{{name}}\"? Las alertas futuras que cumplan sus condiciones dejarán de etiquetarse.", - "toolbar": { - "search": "Buscar por nombre de regla…", - "allTags": "Todas las etiquetas" - }, - "table": { - "rule": "Regla", - "tags": "Etiquetas", - "conditions": "Condiciones", - "modifiedBy": "Modificado por", - "modifiedDate": "Modificado" - }, - "drawer": { - "createTitle": "Nueva regla de etiquetado", - "edit": "Editar", - "delete": "Eliminar", - "save": "Guardar", - "create": "Crear", - "cancel": "Cancelar" - }, - "form": { - "basics": "Datos básicos", - "name": "Nombre de la regla", - "namePlaceholder": "p. ej. Fuerza bruta SSH interna", - "description": "Descripción", - "descriptionPlaceholder": "Por qué existe esta regla y qué etiqueta.", - "tags": "Etiquetas a aplicar", - "noTags": "No hay etiquetas seleccionadas.", - "addTag": "Agregar etiqueta", - "removeTag": "Quitar", - "noCatalog": "Aún no hay etiquetas en el catálogo.", - "createTag": "Crear etiqueta", - "newTagName": "Nombre de la nueva etiqueta", - "conditions": "Condiciones (deben cumplirse TODAS)", - "noConditions": "Se requiere al menos una condición.", - "addCondition": "Agregar condición", - "removeCondition": "Quitar condición", - "valuePlaceholder": "Valor", - "valueListPlaceholder": "Valores separados por comas", - "incomplete": "Completa el nombre de la regla, la descripción, al menos una etiqueta y todas las condiciones." - }, - "view": { - "description": "Descripción", - "tags": "Etiquetas", - "conditions": "Condiciones", - "audit": "Auditoría", - "createdBy": "Creado por", - "createdDate": "Creado", - "modifiedBy": "Modificado por", - "modifiedDate": "Modificado" - }, - "toast": { - "created": "Regla \"{{name}}\" creada.", - "updated": "Regla \"{{name}}\" actualizada.", - "deleted": "Regla \"{{name}}\" eliminada.", - "createError": "No se pudo crear la regla.", - "updateError": "No se pudo actualizar la regla.", - "deleteError": "No se pudo eliminar la regla." - }, - "deleteTitle": "Eliminar regla de etiquetado" - }, - "threatIntel": { - "header": { - "matchedInEnv": "coincidencias en tu entorno", - "export": "Exportar IOCs", - "exporting": "Exportando…", - "noInstanceIocs": "Sin indicadores de instancia — mostrando datos genéricos", - "noInstanceIocsHint": "No se observaron indicadores en tus alertas — se muestran datos genéricos de feeds." - }, - "overview": { - "title": "Coincidencias de IOCs", - "totalIndicators": "indicadores totales", - "families": { - "ip": "IP", - "url": "URL", - "domain": "Dominio", - "signatures": "Firmas" - } - }, - "notConfigured": { - "title": "Threat Intelligence no está configurado", - "body": "Contacta a tu administrador para conectar una instancia de Cyber Mantra / ThreatWinds para este entorno." - }, - "lookup": { - "title": "Busca cualquier indicador", - "placeholder": "Pega una IP, dominio, hash, URL o CVE — revisaremos feeds y tu entorno", - "button": "Buscar", - "busy": "Buscando…" - }, - "tabs": { - "iocs": "IOCs", - "actors": "Actores de amenaza", - "feeds": "Feeds", - "analyst": "Analista de IA" - }, - "toolbar": { - "searchPlaceholders": { - "iocs": "Busca IOC, etiqueta, fuente…", - "actors": "Busca actores, alias, técnicas…", - "feeds": "Busca feeds…" - }, - "last24h": "Últimas 24 horas", - "filters": "Filtros", - "refresh": "Actualizar" - }, - "iocs": { - "table": { - "type": "Tipo", - "indicator": "Indicador", - "reputation": "Reputación", - "tags": "Etiquetas", - "lastSeen": "Última vez visto" - }, - "empty": "Sin coincidencias de IOCs.", - "loadingMore": "Cargando más…", - "loadedProgress": "Cargados {{loaded}} de {{total}}. Desplázate para más.", - "endOfResults": "Fin de resultados ({{loaded}} de {{total}})." - }, - "drawer": { - "loading": "Cargando…", - "accuracy": "Precisión:", - "actions": { - "block": "Bloquear en perímetro", - "viewEvents": "Ver eventos coincidentes", - "externalLookup": "Búsqueda externa", - "trackCampaign": "Rastrear campaña", - "viewIocs": "Ver IOCs coincidentes", - "mitre": "MITRE ATT&CK" - }, - "sections": { - "timeline": "Cronología", - "networkOrigin": "Red / origen", - "associationsWithCount": "Asociaciones ({{count}})", - "geolocationsWithCount": "Geolocalizaciones ({{count}})", - "about": "Acerca de", - "activity": "Actividad" - }, - "fields": { - "firstSeen": "Primera vez visto", - "lastSeen": "Última vez visto", - "country": "País", - "city": "Ciudad", - "aso": "ASO", - "asn": "ASN", - "reputation": "Reputación", - "accuracy": "Precisión", - "current": "Actual", - "best": "Mejor", - "worst": "Peor" - }, - "aiBrief": "Resumen IA", - "noDescription": "No hay descripción disponible para este indicador.", - "lastObserved": "Última observación {{when}}." - }, - "actors": { - "empty": "Sin actores encontrados." }, - "feeds": { - "empty": "Sin feeds configurados.", - "table": { - "name": "Feed", - "type": "Tipo", - "accuracy": "Precisión", - "header": "Fuentes", - "format": "Formato" - }, - "download": "Descargar fuente", - "checksum": "Suma de verificación" - }, - "entityTypes": { - "ip": "IP", - "hostname": "Host", - "domain": "Dominio", - "url": "URL", - "hash": "Hash", - "cve": "CVE", - "threat": "Amenaza", - "entity": "Entidad" - }, - "reputation": { - "alarming": "Alarmante", - "suspicious": "Sospechoso", - "indefinable": "Indefinido", - "fair": "Aceptable", - "trustworthy": "Confiable" - }, - "feedAccuracy": { - "level1": "Nivel 1", - "level2": "Nivel 2", - "level3": "Nivel 3" - }, - "triage": { - "title": "Triage", - "subtitle": "Paste indicators, get verdicts", - "input": "Indicators", - "placeholder": "Paste IPs, domains, URLs or hashes — one per line, or comma separated.\nDefanged values (1.2.3[.]4, hxxp://) are accepted.", - "run": "Triage", - "stop": "Stop", - "reset": "Clear", - "parsed": "{{count}} unique indicators", - "capped": "Capped at {{max}} per run.", - "progress": "{{done}} of {{total}}", - "empty": "Paste indicators above to begin.", - "indicator": "Indicator", - "type": "Type", - "verdict": "Verdict", - "reputation": "Rep", - "accuracy": "Acc", - "tags": "Tags", - "lastSeen": "Last seen", - "exportCsv": "Export CSV", - "exportStix": "Export STIX", - "stixNote": "STIX export includes malicious and suspicious rows only.", - "open": "Open", - "notConfigured": "Threat intelligence is not configured — triage needs an upstream ThreatWinds instance.", - "summary": "Summary", - "v.malicious": "Malicious", - "v.suspicious": "Suspicious", - "v.benign": "Benign", - "v.unknown": "Unknown", - "v.notFound": "Not found", - "v.invalid": "Unrecognised" - }, - "report": { - "title": "Reportar", - "subtitle": "Publicar un indicador en el grafo ThreatWinds", - "submit": "Reportar indicador", - "submitting": "Reportando…", - "error": { - "generic": "No se pudo enviar el indicador. Inténtalo de nuevo." - }, - "value": { - "label": "Indicador", - "placeholder": "IP, dominio, URL, hash o dirección de correo" - }, - "type": { - "label": "Tipo", - "placeholder": "Inferido del valor", - "inferred": "Inferido: {{type}}", - "inferenceFailed": "No se pudo inferir ningún tipo de este valor. Elige uno de la lista o escríbelo.", - "unknown": "«{{type}}» no es un tipo de entidad. Elige uno de la lista." - }, - "tags": { - "label": "Etiquetas", - "placeholder": "phishing, robo-de-credenciales" - }, - "description": { - "label": "Notas" - }, - "reputation": { - "legend": "Reputación", - "hint": "Déjalo sin establecer si no has llegado a un veredicto.", - "alarming": "Alarmante", - "worrying": "Preocupante", - "concerning": "Sospechoso", - "indefinable": "Indefinible", - "adequate": "Adecuado", - "good": "Bueno", - "exceptional": "Excelente" - }, - "associations": { - "legend": "Indicadores relacionados", - "add": "Añadir indicador relacionado", - "remove": "Eliminar", - "valuePlaceholder": "Valor relacionado", - "typePlaceholder": "Tipo (opcional)", - "modeLabel": "Relación", - "mode": { - "association": "Relacionado con", - "aggregation": "Parte de" - }, - "visibilityConflict": "No comparte ningún grupo de visibilidad con el indicador de arriba. Se rechazaría todo el envío." - }, - "attributes": { - "legend": "Detalles", - "hint": "Opcional. Lo que quede en blanco no se envía.", - "invalidHex": "Se esperan {{length}} caracteres hexadecimales.", - "invalidHexAny": "Solo se aceptan caracteres hexadecimales.", - "invalidNumber": "Se espera un número." - }, - "correlate": { - "legend": "Correlacionar", - "hint": "Cada atributo marcado se publica como entidad propia, vinculada a esta.", - "count_one": "Crea {{count}} entidad vinculada.", - "count_other": "Crea {{count}} entidades vinculadas." - }, - "scan": { - "notice": "Reportar esto también encola un análisis del destino." - }, - "receipt": { - "title": "Enviado", - "noVerdict": "Sin veredicto", - "skipped": "No enviado, no se pudo inferir el tipo", - "pending": "Esperando a que el indicador aparezca en el corpus…", - "live": "Activo en el corpus — ver entidad", - "processing": "Siguiendo en proceso de ingestión. Aparecerá cuando el flujo se ponga al día.", - "another": "Reportar otro" - }, - "visibility": { - "legend": "Visible para" - }, - "example": "Probar ejemplo" - } - }, - "playground": { - "titleFilter": "Probar pipeline", - "titleRule": "Probar regla", - "noDataTypes": "Este pipeline aún no tiene tipos de datos asignados — añade uno para probarlo.", - "dataTypeLabel": "Tipo de dato", - "dataTypePlaceholder": "No hay tipos de datos disponibles", - "dataTypeSingleHint": "Este pipeline solo tiene un tipo de dato — añade más para poder elegir.", - "rawLogLabel": "Log en crudo", - "rawLogPlaceholder": "Pega una línea de log de ejemplo…", - "rawLogCounter": "{{chars}} caracteres · {{kb}} KB", - "rawLogTooLarge": "Este log supera el límite de 1 MB — recórtalo antes de ejecutar la prueba.", - "run": { - "label": "Ejecutar", - "running": "Probando…", - "waitHint": "Esto puede tardar hasta 15 segundos mientras el pipeline procesa el log." - }, - "errors": { - "busy": "El playground está ocupado con otra prueba — inténtalo de nuevo en un momento.", - "timeout": "La prueba agotó el tiempo — normalmente significa que el tipo de dato seleccionado no coincide con el formato del log.", - "validation": "La solicitud no era válida — revisa el log en crudo y el contenido del pipeline.", - "server": "El playground no pudo completar la prueba — inténtalo de nuevo." - }, - "notices": { - "geo": "El plugin de geolocation no está disponible para esta versión lite del test de filtros y reglas.", - "correlation": "Las reglas que consultan eventos previos mediante las cláusulas afterEvent o correlation requieren que ya existan eventos coincidentes en el sistema para que la alerta bajo prueba se dispare." - }, - "result": { - "label": "Resultado procesado", - "empty": "Ejecuta una prueba para ver aquí el evento procesado.", - "loading": "Esperando el evento procesado…", - "tabs": { - "fields": "Campos", - "json": "JSON" - }, - "fieldsCount_one": "{{count}} campo", - "fieldsCount_other": "{{count}} campos", - "copy": "Copiar", - "copied": "Copiado", - "elapsed": "Procesado en {{time}}", - "elapsedHint": "Tiempo desde Ejecutar hasta el resultado procesado", - "searchPlaceholder": "Buscar campos…", - "noMatch": "Ningún campo coincide con tu búsqueda." - }, - "alerts": { - "label": "Alertas", - "empty": "Ejecuta una prueba para ver aquí las alertas resultantes.", - "none": "No se activó ninguna alerta.", - "count_one": "{{count}} alerta", - "count_other": "{{count}} alertas" - }, - "title": "Test pipeline" - }, - "tenants": { - "title": "Tenants", - "new": "Nuevo tenant", - "subtitle": "Cada cliente que corre en esta instancia, lo que tiene y lo que te deja ver.", - "searchPlaceholder": "Buscar por nombre o dominio…", - "loading": "Cargando tenants…", - "loadFailed": "No se pudieron cargar los tenants.", - "retry": "Reintentar", - "none": "Todavía no hay tenants.", - "noSearchMatch": "Ningún tenant coincide con la búsqueda.", - "cancel": "Cancelar", - "saving": "Guardando…", - "chips": { - "total": "tenants", - "active": "activos", - "readable": "con acceso" - }, - "status": { - "ACTIVE": "Activo", - "SUSPENDED": "Suspendido", - "TERMINATED": "Terminado" - }, - "support": { - "NONE": "Sin acceso", - "READ": "Acceso de lectura", - "FULL": "Acceso total", - "hint": "Lo concede el tenant, no tú. Solo su administrador puede cambiarlo." - }, - "card": { - "edit": "Editar", - "activate": "Activar", - "deactivate": "Desactivar", - "deletePermanent": "Eliminar permanentemente", - "noAccess": "Este tenant no te ha dado acceso.", - "loadingStats": "Leyendo…", - "enter": "Entrar" - }, - "stats": { - "users": "Usuarios", - "datasources": "Fuentes", - "openAlerts": "Alertas abiertas", - "ai": "IA hoy", - "noLimit": "sin tope" - }, - "fields": { - "name": "Nombre", - "domain": "Dominio", - "domainHint": "Por dónde se llega a este tenant. Toda petición a ese host entra en sus datos.", - "adminEmail": "Correo del administrador", - "adminEmailHint": "Recibe una invitación para poner su propia contraseña.", - "status": "Estado", - "suspendedWarning": "Un tenant suspendido no puede iniciar sesión. Sus datos se conservan.", - "aiLimit": "Tope de peticiones de IA", - "aiLimitHint": "Un tope operativo, por día. Sin tope, gastan contra la licencia de la instancia.", - "aiLimitToggle": "Poner tope a este tenant" - }, - "create": { - "title": "Nuevo tenant", - "subtitle": "Crea el tenant e invita a su primer administrador.", - "submit": "Crear tenant" - }, - "edit": { - "title": "Editar tenant", - "subtitle": "El acceso de soporte no está aquí: solo el tenant puede concederlo.", - "submit": "Guardar cambios" - }, - "terminate": { - "title": "¿Desactivar este tenant?", - "body": "Nadie de {{name}} podrá iniciar sesión. Sus datos se conservan, así que es reversible, pero deja al cliente fuera ahora mismo.", - "confirmLabel": "Escribe {{name}} para confirmar", - "submit": "Desactivar" - }, - "reactivate": { - "title": "¿Activar este tenant?", - "body": "{{name}} podrá iniciar sesión de nuevo. Sus datos conservados se restauran tal cual.", - "submit": "Activar" - }, - "deletePermanent": { - "title": "¿Eliminar este tenant para siempre?", - "body": "Todo rastro de {{name}} — usuarios, fuentes de datos, dashboards, alertas, integraciones — será borrado. Esto no se puede deshacer.", - "confirmLabel": "Escribe {{name}} para confirmar", - "submit": "Eliminar para siempre" - }, - "toast": { - "created": "Tenant creado", - "updated": "Tenant actualizado", - "terminated": "Tenant terminado", - "reactivated": "Tenant reactivado", - "permanentlyDeleted": "Tenant eliminado permanentemente", - "domainInUse": "Ese dominio ya está en uso", - "noPermission": "No tienes permiso para hacer eso", - "notFound": "Tenant no encontrado", - "invalidRequest": "Petición inválida", - "operationFailed": "La operación falló" - }, - "switcher": { - "aria": "Switch tenant", - "self": "Default tenant", - "create": "Create tenant" - } - }, - "supportAccess": { - "title": "Acceso de soporte", - "intro": "Quien opera esta instancia no puede mirar dentro de tus datos salvo que se lo permitas. Aquí no se concede nada por defecto, y puedes retirarlo cuando quieras.", - "loading": "Cargando…", - "loadFailed": "No se pudo leer la configuración actual.", - "retry": "Reintentar", - "currentBadge": "actual", - "save": "Guardar", - "saving": "Guardando…", - "levels": { - "NONE": { - "name": "Sin acceso", - "desc": "El operador ve que tu tenant existe y nada más. Cualquier petición a tus datos se rechaza." - }, - "READ": { - "name": "Solo lectura", - "desc": "El operador puede mirar tus alertas, logs y configuración para ayudarte. No puede cambiar nada: toda escritura se rechaza, diga lo que diga su propio rol." - }, - "FULL": { - "name": "Acceso total", - "desc": "El operador puede actuar dentro de tu tenant como administrador: cambiar configuración, usuarios y flujos de respuesta." - } - }, - "fullWarning": "El acceso total le permite cambiar cosas en tu nombre. Concédelo mientras necesites ayuda directa y vuelve atrás después.", - "revokeNote": "Todo lo que el operador haga aquí queda registrado en tu log de auditoría.", - "toast": { - "granted": "Acceso de soporte actualizado", - "revoked": "Acceso de soporte retirado", - "forbidden": "Solo un administrador de este tenant puede cambiar esto", - "invalid": "Petición inválida", - "failed": "No se pudo guardar el cambio" - } - }, - "supportSession": { - "inside": "Estás trabajando dentro de {{name}}", - "readOnly": "solo lectura — las escrituras se rechazan", - "full": "acceso total — lo que cambies aquí es real", - "leave": "Salir" - }, - "platformBroadcast": { - "button": "Aplicar a todos los inquilinos", - "action": { - "create": "Difundir creación de {{resource}}", - "update": "Difundir actualización de {{resource}}", - "delete": "Difundir eliminación de {{resource}}", - "toggle": "Difundir alternancia de {{resource}}", - "enable": "Difundir activación de {{resource}}", - "activate": "Difundir activación de {{resource}}", - "test": "Difundir prueba de {{resource}}", - "upload": "Difundir activo {{resource}}" - }, - "resource": { - "pipeline": "pipeline", - "correlationRule": "regla de correlación", - "soarFlow": "flujo SOAR", - "framework": "marco", - "control": "control", - "smtp": "SMTP", - "idp": "proveedor de identidad", - "branding": "marca" - }, - "warning": { - "title": "Esta acción se ejecutará en cada inquilino seleccionado.", - "body": "Los fallos por inquilino se informan al terminar y no se revierten." - }, - "allTenants": "Aplicar a todos los inquilinos", - "excludesDefault": "El inquilino de la plataforma se excluye de esta acción.", - "searchPlaceholder": "Buscar inquilinos…", - "loading": "Cargando inquilinos…", - "empty": "Ningún inquilino coincide.", - "targetCount": "Se aplicará a {{count}} inquilino(s).", - "platformTenant": "plataforma", - "confirm": "Aplicar a {{count}} inquilino(s)", - "result": { - "succeeded": "Exitosos", - "noneSucceeded": "Ningún inquilino tuvo éxito.", - "failed": "Fallidos", - "noneFailed": "Sin fallos." - } - }, - "tiAnalyst": { - "console": { - "subtitle": "Espacio del analista", - "model": "Modelo", - "resizeResults": "Redimensionar el panel de resultados", - "resizeHint": "Arrastrar para redimensionar · doble clic para restablecer" - }, - "conv": { - "title": "Conversaciones", - "allConversations": "Todas las conversaciones", - "empty": "Aún no hay conversaciones.", - "new": "Nueva conversación", - "newTitle": "Título de la conversación", - "selectPrompt": "Seleccione una conversación o comience una.", - "running": "en curso", - "delete": "Eliminar {{title}}", - "unread_one": "{{count}} mensaje no leído", - "unread_other": "{{count}} mensajes no leídos", - "transcript": "Transcripción de la conversación" - }, - "agent": { - "placeholder": "Investigar un indicador…", - "ask": "Preguntar al agente analista", - "intro": "Pregunte sobre cualquier indicador. El agente consulta ThreatWinds directamente y muestra su trabajo.", - "send": "Enviar", - "stop": "Detener", - "thinking": "reflexionando…", - "suggestionInvestigate": "Investiga 8.8.8.8 y dime si es malicioso", - "suggestionInfrastructure": "¿Qué infraestructura está relacionada con google.com?", - "suggestionCounts": "Muéstrame cuántas entidades existen por tipo" + "supportAccess": { + "title": "Acceso de soporte", + "intro": "Quien opera esta instancia no puede mirar dentro de tus datos salvo que se lo permitas. Aquí no se concede nada por defecto, y puedes retirarlo cuando quieras.", + "loading": "Cargando…", + "loadFailed": "No se pudo leer la configuración actual.", + "retry": "Reintentar", + "currentBadge": "actual", + "save": "Guardar", + "saving": "Guardando…", + "levels": { + "NONE": { + "name": "Sin acceso", + "desc": "El operador ve que tu tenant existe y nada más. Cualquier petición a tus datos se rechaza." + }, + "READ": { + "name": "Solo lectura", + "desc": "El operador puede mirar tus alertas, logs y configuración para ayudarte. No puede cambiar nada: toda escritura se rechaza, diga lo que diga su propio rol." + }, + "FULL": { + "name": "Acceso total", + "desc": "El operador puede actuar dentro de tu tenant como administrador: cambiar configuración, usuarios y flujos de respuesta." + } + }, + "fullWarning": "El acceso total le permite cambiar cosas en tu nombre. Concédelo mientras necesites ayuda directa y vuelve atrás después.", + "revokeNote": "Todo lo que el operador haga aquí queda registrado en tu log de auditoría.", + "toast": { + "granted": "Acceso de soporte actualizado", + "revoked": "Acceso de soporte retirado", + "forbidden": "Solo un administrador de este tenant puede cambiar esto", + "invalid": "Petición inválida", + "failed": "No se pudo guardar el cambio" + } }, - "canvas": { - "title": "Resultados", - "empty": "Los resultados de esta conversación aparecen aquí.", - "tile": "Ordenar", - "closeAll": "Cerrar todo", - "pinOut": "Abrir {{title}} como panel", - "loading": "cargando…", - "failed": "no se pudo cargar", - "noRelations": "sin entidades relacionadas", - "noGeo": "sin geolocalización registrada", - "noResults": "sin coincidencias", - "matches": "{{total}} coincidencias", - "panelName": "{{title}} — {{kind}}", - "movePanel": "Mover {{title}}", - "resizePanel": "Redimensionar {{title}}", - "closePanel": "Cerrar {{title}}", - "collapse": "Reducir {{title}}", - "expand": "Expandir {{title}}", - "kind": { - "entity": "expediente", - "graph": "relaciones", - "geo": "geolocalización", - "search": "búsqueda" - } + "supportSession": { + "inside": "Estás trabajando dentro de {{name}}", + "readOnly": "solo lectura — las escrituras se rechazan", + "full": "acceso total — lo que cambies aquí es real", + "leave": "Salir" + }, + "platformBroadcast": { + "button": "Aplicar a todos los inquilinos", + "action": { + "create": "Difundir creación de {{resource}}", + "update": "Difundir actualización de {{resource}}", + "delete": "Difundir eliminación de {{resource}}", + "toggle": "Difundir alternancia de {{resource}}", + "enable": "Difundir activación de {{resource}}", + "activate": "Difundir activación de {{resource}}", + "test": "Difundir prueba de {{resource}}", + "upload": "Difundir activo {{resource}}" + }, + "resource": { + "pipeline": "pipeline", + "correlationRule": "regla de correlación", + "soarFlow": "flujo SOAR", + "framework": "marco", + "control": "control", + "smtp": "SMTP", + "idp": "proveedor de identidad", + "branding": "marca" + }, + "warning": { + "title": "Esta acción se ejecutará en cada inquilino seleccionado.", + "body": "Los fallos por inquilino se informan al terminar y no se revierten." + }, + "allTenants": "Aplicar a todos los inquilinos", + "excludesDefault": "El inquilino de la plataforma se excluye de esta acción.", + "searchPlaceholder": "Buscar inquilinos…", + "loading": "Cargando inquilinos…", + "empty": "Ningún inquilino coincide.", + "targetCount": "Se aplicará a {{count}} inquilino(s).", + "platformTenant": "plataforma", + "confirm": "Aplicar a {{count}} inquilino(s)", + "result": { + "succeeded": "Exitosos", + "noneSucceeded": "Ningún inquilino tuvo éxito.", + "failed": "Fallidos", + "noneFailed": "Sin fallos." + } }, - "graph": { - "nodes_one": "{{count}} nodo", - "nodes_other": "{{count}} nodos", - "edges_one": "{{count}} arista", - "edges_other": "{{count}} aristas", - "clickToPivot": "clic para pivotar", - "malicious": "malicioso", - "unknown": "desconocido", - "benign": "inofensivo" + "tiAnalyst": { + "console": { + "subtitle": "Espacio del analista", + "model": "Modelo", + "resizeResults": "Redimensionar el panel de resultados", + "resizeHint": "Arrastrar para redimensionar · doble clic para restablecer" + }, + "conv": { + "title": "Conversaciones", + "allConversations": "Todas las conversaciones", + "empty": "Aún no hay conversaciones.", + "new": "Nueva conversación", + "newTitle": "Título de la conversación", + "selectPrompt": "Seleccione una conversación o comience una.", + "running": "en curso", + "delete": "Eliminar {{title}}", + "unread_one": "{{count}} mensaje no leído", + "unread_other": "{{count}} mensajes no leídos", + "transcript": "Transcripción de la conversación" + }, + "agent": { + "placeholder": "Investigar un indicador…", + "ask": "Preguntar al agente analista", + "intro": "Pregunte sobre cualquier indicador. El agente consulta ThreatWinds directamente y muestra su trabajo.", + "send": "Enviar", + "stop": "Detener", + "thinking": "reflexionando…", + "suggestionInvestigate": "Investiga 8.8.8.8 y dime si es malicioso", + "suggestionInfrastructure": "¿Qué infraestructura está relacionada con google.com?", + "suggestionCounts": "Muéstrame cuántas entidades existen por tipo" + }, + "canvas": { + "title": "Resultados", + "empty": "Los resultados de esta conversación aparecen aquí.", + "tile": "Ordenar", + "closeAll": "Cerrar todo", + "pinOut": "Abrir {{title}} como panel", + "loading": "cargando…", + "failed": "no se pudo cargar", + "noRelations": "sin entidades relacionadas", + "noGeo": "sin geolocalización registrada", + "noResults": "sin coincidencias", + "matches": "{{total}} coincidencias", + "panelName": "{{title}} — {{kind}}", + "movePanel": "Mover {{title}}", + "resizePanel": "Redimensionar {{title}}", + "closePanel": "Cerrar {{title}}", + "collapse": "Reducir {{title}}", + "expand": "Expandir {{title}}", + "kind": { + "entity": "expediente", + "graph": "relaciones", + "geo": "geolocalización", + "search": "búsqueda" + } + }, + "graph": { + "nodes_one": "{{count}} nodo", + "nodes_other": "{{count}} nodos", + "edges_one": "{{count}} arista", + "edges_other": "{{count}} aristas", + "clickToPivot": "clic para pivotar", + "malicious": "malicioso", + "unknown": "desconocido", + "benign": "inofensivo" + }, + "entity": { + "reputation": "Reputación", + "accuracy": "Precisión", + "worst": "Peor", + "best": "Mejor", + "relations": "Grafo de relaciones", + "history": "Historial", + "geolocations": "Geolocalizaciones", + "associations": "Asociaciones", + "radius": "r={{radius}}m", + "askAgentBtn": "Preguntar al agente", + "askAgent": "Evalúa {{type}} {{value}} (entidad id {{id}}). ¿Es una amenaza?" + }, + "tool": { + "querying": "consultando…", + "notRetained": "Resultado no conservado.", + "expand": "Mostrar solicitud y resultado", + "collapse": "Ocultar solicitud y resultado", + "noIntel": "«{{value}}» no tiene información de amenazas registrada.", + "noMatches": "Sin coincidencias.", + "matches": "{{items}} coincidencias para «{{query}}»", + "more": "+{{count}} más", + "reported": "Reportado al corpus compartido de ThreatWinds. La ingesta es asincrona, no es inmediatamente consultable.", + "skippedAssociations": "No registrado (tipo no inferible): {{values}}" + } }, - "entity": { - "reputation": "Reputación", - "accuracy": "Precisión", - "worst": "Peor", - "best": "Mejor", - "relations": "Grafo de relaciones", - "history": "Historial", - "geolocations": "Geolocalizaciones", - "associations": "Asociaciones", - "radius": "r={{radius}}m", - "askAgentBtn": "Preguntar al agente", - "askAgent": "Evalúa {{type}} {{value}} (entidad id {{id}}). ¿Es una amenaza?" + "threatwinds": { + "title": "Integración de ThreatWinds", + "subtitle": "Comparte los incidentes de esta instancia con el feed comunitario de ThreatWinds.", + "feeds": "Habilitar feeds", + "feedsHint": "Cuando está activado, los eventos se comprueban contra los feeds de inteligencia de ThreatWinds.", + "contribute": "Contribuir incidentes", + "contributeHint": "Cuando está activado, los incidentes de esta instancia se envían a ThreatWinds.", + "loading": "Cargando estado de la integración…", + "failed": "No se pudo cargar el estado de la integración de ThreatWinds.", + "retry": "Reintentar", + "toast": { + "enabled": "Contribución activada", + "disabled": "Contribución desactivada", + "failed": "No se pudo actualizar la configuración de contribución" + } }, - "tool": { - "querying": "consultando…", - "notRetained": "Resultado no conservado.", - "expand": "Mostrar solicitud y resultado", - "collapse": "Ocultar solicitud y resultado", - "noIntel": "«{{value}}» no tiene información de amenazas registrada.", - "noMatches": "Sin coincidencias.", - "matches": "{{items}} coincidencias para «{{query}}»", - "more": "+{{count}} más", - "reported": "Reportado al corpus compartido de ThreatWinds. La ingesta es asincrona, no es inmediatamente consultable.", - "skippedAssociations": "No registrado (tipo no inferible): {{values}}" - } - }, - "threatwinds": { - "title": "Integración de ThreatWinds", - "subtitle": "Comparte los incidentes de esta instancia con el feed comunitario de ThreatWinds.", - "feeds": "Habilitar feeds", - "feedsHint": "Cuando está activado, los eventos se comprueban contra los feeds de inteligencia de ThreatWinds.", - "contribute": "Contribuir incidentes", - "contributeHint": "Cuando está activado, los incidentes de esta instancia se envían a ThreatWinds.", - "loading": "Cargando estado de la integración…", - "failed": "No se pudo cargar el estado de la integración de ThreatWinds.", - "retry": "Reintentar", - "toast": { - "enabled": "Contribución activada", - "disabled": "Contribución desactivada", - "failed": "No se pudo actualizar la configuración de contribución" - } - }, - "liveOps": { - "header": "Operaciones en vivo", - "live": "EN VIVO", - "replay": "REPRODUCCIÓN", - "statLastHour": "Última hora", - "statHigh": "Altas", - "statOpen": "Abiertas", - "statAttackers": "Atacantes", - "listTitle": "Alertas", - "listShown": "{{count}} mostradas", - "listShow": "Mostrar la lista de alertas", - "listHide": "Ocultar la lista", - "agoJust": "ahora", - "agoMin": "hace {{count}} min", - "agoH": "hace {{count}} h", - "more": "Más", - "less": "Menos", - "loading": "Cargando alertas…", - "error": "No se pudieron cargar las alertas: {{msg}}", - "empty": "No hay alertas en el almacén.", - "onStage": "En pantalla", - "hideDetails": "Ocultar este panel", - "showDetails": "Mostrar los detalles", - "inIncident": "En un incidente", - "openInAlerts": "Abrir en Alertas", - "involved": "Implicados", - "askSocAi": "Preguntar a SOC-AI", - "askExplain": "Explica este ataque y dime qué hacer a continuación", - "askFp": "¿Es un falso positivo?", - "askAttacker": "¿Qué más hizo este atacante?", - "timCount": "{{count}} alertas en la última {{range}}", - "timPrev": "Alerta anterior", - "timNext": "Alerta siguiente", - "timReplay": "Reproducir ventana", - "timStop": "Detener reproducción", - "timLive": "EN VIVO", - "timNow": "ahora", - "kb": { - "bruteForce": "Fuerza bruta", - "outbound": "Conexión a un destino malicioso", - "lateral": "Movimiento lateral", - "malware": "Ejecución maliciosa en un equipo", - "webAttack": "Ataque web", - "travel": "Viaje imposible", - "scan": "Baneo de puertos", - "cloud": "Cambio riesgoso en la nube", - "generic": "Detección", - "ransomware": "Ransomware en un host", - "persistence": "Mecanismo de persistencia", - "exfil": "Exfiltración de datos", - "defenseEvasion": "Evasión de defensas", - "privEsc": "Escalada de privilegios", - "userExec": "Usuario abre un archivo malicioso", - "softwareDeploy": "Software enviada a un host", - "phishing": "Correo de phishing abierto", - "processInjection": "Código inyectado en un proceso", - "credDump": "Credenciales robadas", - "dataDestruction": "Datos destruidos", - "toolDownload": "Herramienta descargada y ejecutada", - "c2tunnel": "C2 a través de túnel", - "iocMatch": "Coincidencia IOC de amenaza", - "perimeterDetect": "Detección de perímetro/IDS", - "accountChange": "Cambio de cuenta o política", - "kerberosTicket": "Abuso de tickets Kerberos", - "powershellAbuse": "Abuso de scripting", - "reverseShell": "Reverse shell", - "vmEscape": "Escape de VM/hipervisor" + "liveOps": { + "header": "Operaciones en vivo", + "live": "EN VIVO", + "replay": "REPRODUCCIÓN", + "statLastHour": "Última hora", + "statHigh": "Altas", + "statOpen": "Abiertas", + "statAttackers": "Atacantes", + "listTitle": "Alertas", + "listShown": "{{count}} mostradas", + "listShow": "Mostrar la lista de alertas", + "listHide": "Ocultar la lista", + "agoJust": "ahora", + "agoMin": "hace {{count}} min", + "agoH": "hace {{count}} h", + "more": "Más", + "less": "Menos", + "loading": "Cargando alertas…", + "error": "No se pudieron cargar las alertas: {{msg}}", + "empty": "No hay alertas en el almacén.", + "onStage": "En pantalla", + "hideDetails": "Ocultar este panel", + "showDetails": "Mostrar los detalles", + "inIncident": "En un incidente", + "openInAlerts": "Abrir en Alertas", + "involved": "Implicados", + "askSocAi": "Preguntar a SOC-AI", + "askExplain": "Explica este ataque y dime qué hacer a continuación", + "askFp": "¿Es un falso positivo?", + "askAttacker": "¿Qué más hizo este atacante?", + "timCount": "{{count}} alertas en la última {{range}}", + "timPrev": "Alerta anterior", + "timNext": "Alerta siguiente", + "timReplay": "Reproducir ventana", + "timStop": "Detener reproducción", + "timLive": "EN VIVO", + "timNow": "ahora", + "kb": { + "bruteForce": "Fuerza bruta", + "outbound": "Conexión a un destino malicioso", + "lateral": "Movimiento lateral", + "malware": "Ejecución maliciosa en un equipo", + "webAttack": "Ataque web", + "travel": "Viaje imposible", + "scan": "Baneo de puertos", + "cloud": "Cambio riesgoso en la nube", + "generic": "Detección", + "ransomware": "Ransomware en un host", + "persistence": "Mecanismo de persistencia", + "exfil": "Exfiltración de datos", + "defenseEvasion": "Evasión de defensas", + "privEsc": "Escalada de privilegios", + "userExec": "Usuario abre un archivo malicioso", + "softwareDeploy": "Software enviada a un host", + "phishing": "Correo de phishing abierto", + "processInjection": "Código inyectado en un proceso", + "credDump": "Credenciales robadas", + "dataDestruction": "Datos destruidos", + "toolDownload": "Herramienta descargada y ejecutada", + "c2tunnel": "C2 a través de túnel", + "iocMatch": "Coincidencia IOC de amenaza", + "perimeterDetect": "Detección de perímetro/IDS", + "accountChange": "Cambio de cuenta o política", + "kerberosTicket": "Abuso de tickets Kerberos", + "powershellAbuse": "Abuso de scripting", + "reverseShell": "Reverse shell", + "vmEscape": "Escape de VM/hipervisor" + }, + "replayTip": "Reproducir todas las alertas de esta ventana en orden", + "liveTip": "Seguir las nuevas alertas a medida que llegan", + "playAgain": "Reproducir esta alerta de nuevo", + "alertAt": "{{name}} a las {{time}}", + "netInternet": "Internet", + "netInternal": "Red interna", + "scUser": "usuario: {{account}}", + "scWrongPassword": "✕ contraseña incorrecta", + "scSignedIn": "✓ iniciado sesión", + "scSignedInAs": "inicio de sesión como {{account}}", + "scFailedSignins": "Inicios de sesión fallidos", + "scBlocked": "🛡 {{name}} bloqueado", + "scSessionAs": "sesión como {{account}}", + "scHost": "Host · {{name}}", + "scFiles": "Documentos", + "scBackups": "Copias de sombra", + "scRansomNote": "🔒 NOTA DE SECUESTRO", + "scShadows": "✕ copias de sombra eliminadas", + "scPersist": "Persistencia", + "scReboot": "sobrevive reinicios: puerta trasera instalada", + "scCloud": "Almacenamiento externo", + "scChunk": "datos", + "scExfilBytes": "Datos exfiltrados", + "scProcessTree": "Árbol de procesos", + "scDns": "¿DNS? {{host}}", + "scThreatIntel": "Intel de amenazas: Alarmante (-3)", + "scConnDropped": "✕ conexión cerrada", + "scPortsProbed": "Puertos sondeados", + "scSignIn": "✓ acceso", + "scKmInMin": "{{km}} km en {{min}} min", + "scAbroad": "en el extranjero", + "scDropped": "{{status}} descartado", + "scBeacon": "baliza", + "capBrute0": "{{name}}{{sub}} empieza a adivinar contraseñas contra {{where}}.", + "capBruteVpn": "el VPN en {{name}}", + "capBrute1": "{{attempts}} inicios de sesión fallidos en {{minutes}} minutos, rotando {{count}} nombres de cuenta.", + "capBrute2": "Un inicio de sesión como {{account}} se ejecuta justo después de los fallos: la contraseña fue adivinada.", + "capBrute3": "Correlación de los fallos entre fuentes: un atacante, muchas cuentas.", + "capBrute4": "Bloquea a {{name}} en el borde{{reset}}.", + "capBruteReset": " y restablece {{account}}", + "capOut1": "{{who}} busca {{dest}}.", + "capOut2": "Se conecta hacia afuera por el puerto {{port}}{{through}}.", + "capOutThrough": ", a través de {{name}}", + "capOut3": "La inteligencia de amenazas coincide con {{dest}}: {{kind}}.", + "capOut4": "La conexión fue descartada y se generó la alerta para que la máquina sea revisada.", + "capOut5": "La conexión se repite: {{name}} probablemente está infectado. Aíslelo y encuentre el proceso.", + "capLat0": "{{name}}{{user}} contacta con {{to}} dentro de la red.", + "capLatUser": " ({{user}})", + "capLat1": "Se autentifica como {{account}} usando {{how}}.", + "capLatHowHash": "un hash de contraseña robado", + "capLatHowKerb": "tickets de servicio Kerberos que puede descifrar sin conexión", + "capLatHowAsrep": "una respuesta Kerberos para una cuenta sin preautenticación", + "capLatHowSmb": "el antiguo protocolo SMBv1", + "capLatHowRdp": "sesiones remotas y compartidos de archivos", + "capLat2": "{{to}} acepta la sesión: el atacante se mueve ahora entre máquinas.", + "capLat3": "Desactive {{account}} y revise ambas máquinas.", + "capMal0": "En {{host}}{{user}} se ejecuta {{proc}}.", + "capMalUser": ", {{user}}", + "capMal1": "{{p0}} inicia {{p1}}: inusual para este programa.", + "capMalChild": "un proceso hijo", + "capMal2": "Se ejecuta {{name}}: {{detail}}.", + "capMalKnown": "una técnica de ataque conocida", + "capMal3": "Detenga el proceso o aísle {{host}}.", + "capWeb0": "{{name}} explora el servidor en {{to}}.", + "capWeb1": "Envía cargas de ataque: {{payloads}}…", + "capWeb2": "{{perimeter}} reconoce las firmas del ataque y descarta las peticiones.", + "capWeb2b": "La IPS reconoce las firmas del ataque y descarta las peticiones.", + "capWeb3": "Algunas peticiones llegan a {{to}}; el servidor responde con errores y un 200 OK.", + "capWeb4": "Bloquee a {{name}} y revise los registros del servidor.", + "capTrv0": "{{user}} inicia sesión desde {{city}}, como de costumbre.", + "capTrv1": "{{gap}} minutos después, la misma cuenta inicia sesión desde {{city}}, {{country}}.", + "capTrvFar": "lejos", + "capTrv2": "{{km}} km en {{gap}} minutos: nadie viaja tan rápido. La contraseña probablemente fue robada.", + "capTrv3": "Revogue las sesiones y restablezca la contraseña de {{user}}.", + "capScn0": "{{name}} empieza a golpear {{to}}, un puerto tras otro.", + "capScn1": "{{count}} puertos sondeados en segundos: SSH, SMB, RDP, bases de datos, consolas web…", + "capScn2": "Los puertos {{open}} responden; el resto están cerrados o filtrados.", + "capScn3": "Suele ser el primer paso de un ataque: bloquee la fuente.", + "capCl0": "{{name}} inicia sesión en {{cloud}}{{from}}.", + "capClFrom": " desde {{country}}", + "capClFromDef": "fuera de la empresa", + "capCl1": "Cambian {{what}}.", + "capCl3": "Confirme que estaba previsto o reviértalo.", + "capGen0": "{{src}} → {{tgt}}", + "capGen1": "{{what}}", + "capGenNew": "Nueva detección", + "capGen2": "Alerta generada: {{name}}.", + "capAlertRaised": "Alerta generada: {{name}}. ", + "capBlocked": "{{ip}} ahora está bloqueado en {{on}}: el tráfico se detiene aquí.", + "destUnknown": "destino desconocido", + "titleBrute": "Fuerza bruta desde {{name}} contra {{to}}", + "titleOut": "{{name}} contactando con {{to}}", + "titleLat": "{{name}} se mueve a {{to}} como {{account}}", + "titleMal": "{{name}} en {{to}}", + "titleWeb": "Ataque web desde {{name}} contra {{to}}", + "titleTrv": "{{name}} inicia sesión desde dos continentes", + "titleScn": "Escaneo de puertos desde {{name}}", + "titleCl": "{{what}} cambiado en {{to}}", + "titleAlert": "Alerta", + "dLsass": "volca la memoria de LSASS para robar contraseñas", + "dMiner": "mina criptomonedas con la CPU del servidor", + "dRev": "abre una shell interactiva de vuelta al atacante", + "dKey": "exporta contraseñas guardadas desde el llavero", + "dTask": "crea una tarea que ejecuta una carga en cada inicio de sesión", + "dAudit": "borra el registro de seguridad de Windows", + "dFw": "elimina las reglas del cortafuegos del host", + "dShadow": "elimina las copias de sombra del volumen antes de cifrar", + "dDump": "herramienta para extraer credenciales", + "dDl": "descarga una herramienta a una carpeta escribible", + "dPs": "ejecuta un comando codificado", + "capRan0": "En {{host}}{{user}}, un proceso empieza a tocar cientos de archivos a la vez.", + "capRanUser": ", {{user}}", + "capRan1": "Los archivos se renombren con {{exts}}: los datos se cifran in situ.", + "capRan2": "Se escribe una nota de secuestro: el atacante pide un pago para restaurar los datos.", + "capRan2b": "Las copias de seguridad y las copias de sombra se eliminan: no hay camino fácil de vuelta.", + "capRan3": "Restaurar desde copias fuera de línea y encontrar el punto de entrada antes de que el cifrado se extienda.", + "titleRan": "Ransomware cifrando {{to}}", + "capPer0": "En {{host}}{{user}}, algo escribe en las ubicaciones de inicio del sistema.", + "capPer1": "Suelta {{what}}: estos se ejecutan automáticamente en cada arranque o inicio de sesión.", + "capPer2": "Última pieza en su sitio: {{what}}. La huella ahora sobrevive reinicios.", + "capPer3": "Eliminar los artefactos de persistencia y buscar el vector de infección inicial.", + "titlePer": "Persistencia instalada en {{to}} vía {{what}}", + "dPersistCron": "ejecuta el payload según un planificador", + "dPersistSd": "inicia el payload en cada arranque", + "dPersistLaunch": "lanza el payload cuando el usuario inicia sesión", + "dPersistKey": "permite al atacante volver por SSH", + "dPersistRc": "ejecuta el payload en cada shell nueva", + "dPersistPs": "ejecuta el payload en cada sesión de PowerShell", + "dPersistPay": "el propio binario del payload", + "capExf0": "En {{host}}{{user}}, datos sensibles se agrupan en un archivo.", + "capExf1": "Empieza a transferirlos hacia fuera usando {{tool}}.", + "capExf2": "Los datos llegan a {{dest}}: ya están fuera de la empresa.", + "capExf3": "Bloquear la transferencia, revocar el acceso a {{dest}} y averiguar quién puede tocar esos datos.", + "titleExf": "{{name}} exfiltrando datos a {{to}}", + "scDefenses": "Defensas", + "scDisabled": "✕ desactivado", + "scLogsCleared": "🗑 registros borrados", + "dEvLog": "traza de auditoría", + "dEvEnf": "aplicación", + "capEv0": "En {{host}}, el atacante empieza a tocar las cosas que lo vigilan.", + "capEv1": "{{what}} se desactiva: una menos que puede verles.", + "capEv2": "Los registros se borran: la pista de lo que hicieron desaparece.", + "capEv2b": "Con {{what}} desactivado, el host queda ciego ante el atacante.", + "capEv3": "Restaurar las herramientas desactivadas y preservar los registros restantes antes de que desaparezcan también.", + "titleEv": "Defensas desactivadas en {{to}}", + "scNormalUser": "usuario normal", + "scToken": "token", + "dEvUac": "UAC evadida", + "dEvToken": "token suplantado", + "dEvSuid": "binario setuid abusado", + "dEvSudo": "caché de sudo abusada", + "dEvExploit": "kernel explotado", + "dEvDefault": "límite de privilegios cruzado", + "capPe0": "En {{host}}, la sesión corre como un usuario normal.{{user}}", + "capPeUser": ", {{user}}", + "capPe1": "Usa {{method}} para alcanzar un nivel de privilegio mayor.", + "capPe2": "Los comandos ahora corren como {{account}}: control total del host.", + "capPe3": "Terminar la sesión escalada y auditar lo que {{account}} pudo tocar.", + "titlePe": "Escalada de privilegios en {{to}} vía {{method}}", + "alertRaised": "Alerta generada", + "userExec": "Usuario abre un archivo malicioso", + "softwareDeploy": "Software enviada a un host", + "phishing": "Correo de phishing abierto", + "processInjection": "Código inyectado en un proceso", + "credDump": "Credenciales robadas", + "dataDestruction": "Datos destruidos", + "toolDownload": "Herramienta descargada y ejecutada", + "c2tunnel": "C2 a través de túnel", + "scExec": "Ejecución", + "scPayload": "→ payload malicioso", + "capUe0": "En {{host}}{{user}}, el usuario descarga un archivo y lo abre.", + "capUeUser": ", {{user}}", + "capUe1": "El archivo se abre: {{file}} se confía y se ejecuta.", + "capUe2": "{{app}} inicia un proceso hijo que ejecuta {{payload}}.", + "capUe3": "Poner el archivo en cuarentena, bloquear su hash y revisar otros equipos que lo abrieron.", + "titleUe": "{{file}} abierto en {{to}}", + "scDeploy": "Despliegue", + "capSd0": "{{src}} envía software hacia {{to}} por la red.", + "capSd1": "Usa {{tool}}: un canal que instala sin interacción del usuario.", + "capSd2": "El paquete se instala en {{to}} y arranca con él.", + "capSd3": "Detener el despliegue, eliminar el componente instalado y auditar qué hizo.", + "titleSd": "Software desplegada de {{src}} a {{to}}", + "scAttachment": "adjunto abierto", + "capPh0": "{{name}} envía un correo de phishing a la empresa.", + "capPh1": "El mensaje llega a la bandeja de {{user}} y se abre.", + "capPh2": "El adjunto se ejecuta: {{file}} corre en la máquina.", + "capPh3": "Poner el correo en cuarentena, bloquear el remitente y quitar {{file}} de la máquina de {{user}}.", + "titlePh": "Correo de phishing abierto por {{user}} (de {{from}})", + "scInject": "Inyección", + "scInside": "— código dentro de un proceso confiable", + "capPi0": "En {{host}}, arranca el cargador del atacante: {{injector}}.", + "capPi1": "Inyecta código en un proceso confiable: {{victim}}.", + "capPi2": "{{victim}} ahora ejecuta el código del atacante con sus propios privilegios.", + "capPi3": "Matar el código inyectado, quitar el cargador y buscar otras víctimas.", + "titlePi": "{{injector}} inyecta código en {{victim}}", + "scCred": "Almacén de credenciales", + "scSecrets": "{{n}} secretos", + "scSecret": "secreto", + "scStolen": "✕ credenciales robadas", + "capCd0": "En {{host}}, una herramienta empieza a leer el almacén de credenciales.", + "capCd1": "Abre {{store}} y extrae el material almacenado.", + "capCd2": "Se capturan {{n}} credenciales: cuentas, claves y hashes.", + "capCd3": "Rotar todas las credenciales del almacén y buscar la herramienta de volcado.", + "titleCd": "{{store}} volcado en {{host}}", + "scData": "Datos", + "scDataItem": "datos-{{i}}", + "scGone": "perdido", + "scNoRecovery": "datos destruidos", + "capDd0": "En {{host}}, algo empieza a borrar datos en vez de cifrarlos.", + "capDd1": "{{n}} conjuntos de datos se destruyen uno tras otro.", + "capDd2": "Los datos se borran a secas: sin nota, sin rescate, sin vuelta.", + "capDd3": "Detener el proceso de origen y restaurar lo que queda desde copias fuera de línea.", + "titleDd": "Datos destruidos en {{host}}", + "scDownload": "bytes", + "scExecuted": "ejecutado", + "capTd0": "{{src}} sirve una herramienta a {{to}}.", + "capTd1": "Se descarga en una carpeta escribible: {{folder}}.", + "capTd2": "El archivo se ejecuta: {{tool}} ahora corre.", + "capTd3": "Eliminar la herramienta, bloquear su hash y revisar qué hosts la ejecutaron.", + "titleTd": "{{src}} deja una herramienta en {{to}}", + "scTunnel": "oculto en tráfico {{proto}}", + "scTunneled": "Bytes tunelados", + "capCt0": "{{src}} habla con {{to}} usando un protocolo que parece normal.", + "capCt1": "La carga se esconde en el tráfico {{proto}}.", + "capCt2": "Comandos y datos cruzan la frontera sin ser vistos, montados en {{proto}}.", + "capCt3": "Cortar el túnel, bloquear el extremo y revisar qué pasó por él.", + "titleCt": "{{src}} tuneliza C2 por {{proto}} hacia {{to}}", + "netPerimeter": "Perímetro", + "scDc": "Controlador de dominio", + "scObject": "Objeto modificado", + "scChangedBy": "modificado por", + "scHighRisk": "cambio de alto riesgo", + "scTktAsk": "solicitud de ticket", + "scTktUses": "reutilizado en {{n}} servicios", + "scTerminal": "Terminal", + "scRunning": "…ejecutando", + "scAmsiOff": "⚠ AMSI desactivado", + "scConn": "TCP {{port}}", + "scShellOn": "$ reverse shell", + "scHypervisor": "Hipervisor", + "scGuestVm": "máquina virtual invitada", + "scConfined": "confinado al invitado", + "scEscaped": "escapado al host", + "scBoundary": "frontera del invitado cruzada", + "scFeedAsk": "¿feed? {{ioc}}", + "scFeedBad": "MALO", + "scFeedHit": "Intel de amenazas: {{kind}}", + "scDroppedAtFw": "✕ descartado en {{fw}}", + "scTrafficStops": "el tráfico se detiene aquí", + "scSigHits": "Acertos de firma", + "capIoc0": "{{src}} se conecta a {{ioc}}.", + "capIoc1": "La inteligencia de amenazas lo marca: {{kind}}.", + "capIoc2": "{{ioc}} está en la lista de bloqueo: la conexión se corta.", + "capIoc3": "Bloquear {{ioc}} en el borde y revisar qué ya salió de la red.", + "titleIoc": "{{src}} alcanza {{ioc}} conocido", + "capPd0": "{{name}} envía una {{sig}} al perímetro.", + "capPd1": "{{fw}} coincide la firma y dispara.", + "capPd2": "El tráfico se descarta: el perímetro aguantó.", + "capPd3": "El tráfico cruza {{fw}}: la alerta es informativa.", + "capPd4": "Revisar la firma y bloquear la fuente si sigue llegando.", + "titlePd": "{{sig}} bloqueada en {{fw}}", + "capAc0": "{{who}} cambia {{what}} en {{host}}.", + "capAc1": "El {{what}} se modifica.", + "capAc2": "{{before}} → {{after}}.", + "capAc3": "Confirmar que estaba planificado o revertir el cambio de {{who}}.", + "titleAc": "{{what}} cambiado en {{host}}", + "capKb0": "{{src}} pide tickets Kerberos a {{dc}}.", + "capKb1": "El {{ticket}} que obtiene es {{kind}}.", + "capKb2": "Lo reutiliza en {{services}}: el DC lo acepta cada vez.", + "capKb3": "Resetear la contraseña krbtgt y auditar los tickets emitidos en 48 h.", + "titleKb": "{{src}} forja tickets Kerberos vía {{dc}}", + "capPs0": "En {{host}}, un script empieza con contenido codificado.", + "capPs1": "Decodifica un comando y desactiva el sensor antimalware (AMSI).", + "capPs2": "El comando decodificado se ejecuta: es un payload, no un script.", + "capPs2a": "Primero se desactiva AMSI, luego el comando codificado corre sin ser visto.", + "capPs3": "Bloquear el hash y buscar otras máquinas con el mismo script.", + "titlePs2": "Script codificado ejecutándose en {{host}}", + "capRs0": "En {{host}}, un proceso abre un socket hacia afuera.", + "capRs1": "Se conecta de vuelta a {{name}} en el puerto {{port}}: una reverse shell.", + "capRs2": "Aparece un prompt: el atacante ya puede escribir comandos en el host.", + "capRs3": "Matar la conexión, aislar {{host}} y ver qué se tecleó.", + "titleRs": "Reverse shell abierta en {{host}}", + "capVm0": "La VM invitada {{guest}} corre un proceso con acceso a nivel de host.", + "capVm1": "Intenta cruzar la frontera del hipervisor.", + "capVm2": "El proceso corre en el host {{host}}: el invitado ya no es una jaula.", + "capVm3": "Panicar el hipervisor, snapshotear al invitado y reconstruirlo.", + "titleVm": "Invitado {{guest}} escapando a {{host}}", + "listNew": "Nueva", + "newAlertsCount_one": "{{count}} nueva alerta", + "newAlertsCount_other": "{{count}} nuevas alertas", + "statTotal": "Total", + "timPage": "Página {{p}}/{{n}}", + "timPagePrev": "Página anterior", + "timPageNext": "Página siguiente", + "newAlerts": "Nuevas alertas" }, - "replayTip": "Reproducir todas las alertas de esta ventana en orden", - "liveTip": "Seguir las nuevas alertas a medida que llegan", - "playAgain": "Reproducir esta alerta de nuevo", - "alertAt": "{{name}} a las {{time}}", - "netInternet": "Internet", - "netInternal": "Red interna", - "scUser": "usuario: {{account}}", - "scWrongPassword": "✕ contraseña incorrecta", - "scSignedIn": "✓ iniciado sesión", - "scSignedInAs": "inicio de sesión como {{account}}", - "scFailedSignins": "Inicios de sesión fallidos", - "scBlocked": "🛡 {{name}} bloqueado", - "scSessionAs": "sesión como {{account}}", - "scHost": "Host · {{name}}", - "scFiles": "Documentos", - "scBackups": "Copias de sombra", - "scRansomNote": "🔒 NOTA DE SECUESTRO", - "scShadows": "✕ copias de sombra eliminadas", - "scPersist": "Persistencia", - "scReboot": "sobrevive reinicios: puerta trasera instalada", - "scCloud": "Almacenamiento externo", - "scChunk": "datos", - "scExfilBytes": "Datos exfiltrados", - "scProcessTree": "Árbol de procesos", - "scDns": "¿DNS? {{host}}", - "scThreatIntel": "Intel de amenazas: Alarmante (-3)", - "scConnDropped": "✕ conexión cerrada", - "scPortsProbed": "Puertos sondeados", - "scSignIn": "✓ acceso", - "scKmInMin": "{{km}} km en {{min}} min", - "scAbroad": "en el extranjero", - "scDropped": "{{status}} descartado", - "scBeacon": "baliza", - "capBrute0": "{{name}}{{sub}} empieza a adivinar contraseñas contra {{where}}.", - "capBruteVpn": "el VPN en {{name}}", - "capBrute1": "{{attempts}} inicios de sesión fallidos en {{minutes}} minutos, rotando {{count}} nombres de cuenta.", - "capBrute2": "Un inicio de sesión como {{account}} se ejecuta justo después de los fallos: la contraseña fue adivinada.", - "capBrute3": "Correlación de los fallos entre fuentes: un atacante, muchas cuentas.", - "capBrute4": "Bloquea a {{name}} en el borde{{reset}}.", - "capBruteReset": " y restablece {{account}}", - "capOut1": "{{who}} busca {{dest}}.", - "capOut2": "Se conecta hacia afuera por el puerto {{port}}{{through}}.", - "capOutThrough": ", a través de {{name}}", - "capOut3": "La inteligencia de amenazas coincide con {{dest}}: {{kind}}.", - "capOut4": "La conexión fue descartada y se generó la alerta para que la máquina sea revisada.", - "capOut5": "La conexión se repite: {{name}} probablemente está infectado. Aíslelo y encuentre el proceso.", - "capLat0": "{{name}}{{user}} contacta con {{to}} dentro de la red.", - "capLatUser": " ({{user}})", - "capLat1": "Se autentifica como {{account}} usando {{how}}.", - "capLatHowHash": "un hash de contraseña robado", - "capLatHowKerb": "tickets de servicio Kerberos que puede descifrar sin conexión", - "capLatHowAsrep": "una respuesta Kerberos para una cuenta sin preautenticación", - "capLatHowSmb": "el antiguo protocolo SMBv1", - "capLatHowRdp": "sesiones remotas y compartidos de archivos", - "capLat2": "{{to}} acepta la sesión: el atacante se mueve ahora entre máquinas.", - "capLat3": "Desactive {{account}} y revise ambas máquinas.", - "capMal0": "En {{host}}{{user}} se ejecuta {{proc}}.", - "capMalUser": ", {{user}}", - "capMal1": "{{p0}} inicia {{p1}}: inusual para este programa.", - "capMalChild": "un proceso hijo", - "capMal2": "Se ejecuta {{name}}: {{detail}}.", - "capMalKnown": "una técnica de ataque conocida", - "capMal3": "Detenga el proceso o aísle {{host}}.", - "capWeb0": "{{name}} explora el servidor en {{to}}.", - "capWeb1": "Envía cargas de ataque: {{payloads}}…", - "capWeb2": "{{perimeter}} reconoce las firmas del ataque y descarta las peticiones.", - "capWeb2b": "La IPS reconoce las firmas del ataque y descarta las peticiones.", - "capWeb3": "Algunas peticiones llegan a {{to}}; el servidor responde con errores y un 200 OK.", - "capWeb4": "Bloquee a {{name}} y revise los registros del servidor.", - "capTrv0": "{{user}} inicia sesión desde {{city}}, como de costumbre.", - "capTrv1": "{{gap}} minutos después, la misma cuenta inicia sesión desde {{city}}, {{country}}.", - "capTrvFar": "lejos", - "capTrv2": "{{km}} km en {{gap}} minutos: nadie viaja tan rápido. La contraseña probablemente fue robada.", - "capTrv3": "Revogue las sesiones y restablezca la contraseña de {{user}}.", - "capScn0": "{{name}} empieza a golpear {{to}}, un puerto tras otro.", - "capScn1": "{{count}} puertos sondeados en segundos: SSH, SMB, RDP, bases de datos, consolas web…", - "capScn2": "Los puertos {{open}} responden; el resto están cerrados o filtrados.", - "capScn3": "Suele ser el primer paso de un ataque: bloquee la fuente.", - "capCl0": "{{name}} inicia sesión en {{cloud}}{{from}}.", - "capClFrom": " desde {{country}}", - "capClFromDef": "fuera de la empresa", - "capCl1": "Cambian {{what}}.", - "capCl3": "Confirme que estaba previsto o reviértalo.", - "capGen0": "{{src}} → {{tgt}}", - "capGen1": "{{what}}", - "capGenNew": "Nueva detección", - "capGen2": "Alerta generada: {{name}}.", - "capAlertRaised": "Alerta generada: {{name}}. ", - "capBlocked": "{{ip}} ahora está bloqueado en {{on}}: el tráfico se detiene aquí.", - "destUnknown": "destino desconocido", - "titleBrute": "Fuerza bruta desde {{name}} contra {{to}}", - "titleOut": "{{name}} contactando con {{to}}", - "titleLat": "{{name}} se mueve a {{to}} como {{account}}", - "titleMal": "{{name}} en {{to}}", - "titleWeb": "Ataque web desde {{name}} contra {{to}}", - "titleTrv": "{{name}} inicia sesión desde dos continentes", - "titleScn": "Escaneo de puertos desde {{name}}", - "titleCl": "{{what}} cambiado en {{to}}", - "titleAlert": "Alerta", - "dLsass": "volca la memoria de LSASS para robar contraseñas", - "dMiner": "mina criptomonedas con la CPU del servidor", - "dRev": "abre una shell interactiva de vuelta al atacante", - "dKey": "exporta contraseñas guardadas desde el llavero", - "dTask": "crea una tarea que ejecuta una carga en cada inicio de sesión", - "dAudit": "borra el registro de seguridad de Windows", - "dFw": "elimina las reglas del cortafuegos del host", - "dShadow": "elimina las copias de sombra del volumen antes de cifrar", - "dDump": "herramienta para extraer credenciales", - "dDl": "descarga una herramienta a una carpeta escribible", - "dPs": "ejecuta un comando codificado", - "capRan0": "En {{host}}{{user}}, un proceso empieza a tocar cientos de archivos a la vez.", - "capRanUser": ", {{user}}", - "capRan1": "Los archivos se renombren con {{exts}}: los datos se cifran in situ.", - "capRan2": "Se escribe una nota de secuestro: el atacante pide un pago para restaurar los datos.", - "capRan2b": "Las copias de seguridad y las copias de sombra se eliminan: no hay camino fácil de vuelta.", - "capRan3": "Restaurar desde copias fuera de línea y encontrar el punto de entrada antes de que el cifrado se extienda.", - "titleRan": "Ransomware cifrando {{to}}", - "capPer0": "En {{host}}{{user}}, algo escribe en las ubicaciones de inicio del sistema.", - "capPer1": "Suelta {{what}}: estos se ejecutan automáticamente en cada arranque o inicio de sesión.", - "capPer2": "Última pieza en su sitio: {{what}}. La huella ahora sobrevive reinicios.", - "capPer3": "Eliminar los artefactos de persistencia y buscar el vector de infección inicial.", - "titlePer": "Persistencia instalada en {{to}} vía {{what}}", - "dPersistCron": "ejecuta el payload según un planificador", - "dPersistSd": "inicia el payload en cada arranque", - "dPersistLaunch": "lanza el payload cuando el usuario inicia sesión", - "dPersistKey": "permite al atacante volver por SSH", - "dPersistRc": "ejecuta el payload en cada shell nueva", - "dPersistPs": "ejecuta el payload en cada sesión de PowerShell", - "dPersistPay": "el propio binario del payload", - "capExf0": "En {{host}}{{user}}, datos sensibles se agrupan en un archivo.", - "capExf1": "Empieza a transferirlos hacia fuera usando {{tool}}.", - "capExf2": "Los datos llegan a {{dest}}: ya están fuera de la empresa.", - "capExf3": "Bloquear la transferencia, revocar el acceso a {{dest}} y averiguar quién puede tocar esos datos.", - "titleExf": "{{name}} exfiltrando datos a {{to}}", - "scDefenses": "Defensas", - "scDisabled": "✕ desactivado", - "scLogsCleared": "🗑 registros borrados", - "dEvLog": "traza de auditoría", - "dEvEnf": "aplicación", - "capEv0": "En {{host}}, el atacante empieza a tocar las cosas que lo vigilan.", - "capEv1": "{{what}} se desactiva: una menos que puede verles.", - "capEv2": "Los registros se borran: la pista de lo que hicieron desaparece.", - "capEv2b": "Con {{what}} desactivado, el host queda ciego ante el atacante.", - "capEv3": "Restaurar las herramientas desactivadas y preservar los registros restantes antes de que desaparezcan también.", - "titleEv": "Defensas desactivadas en {{to}}", - "scNormalUser": "usuario normal", - "scToken": "token", - "dEvUac": "UAC evadida", - "dEvToken": "token suplantado", - "dEvSuid": "binario setuid abusado", - "dEvSudo": "caché de sudo abusada", - "dEvExploit": "kernel explotado", - "dEvDefault": "límite de privilegios cruzado", - "capPe0": "En {{host}}, la sesión corre como un usuario normal.{{user}}", - "capPeUser": ", {{user}}", - "capPe1": "Usa {{method}} para alcanzar un nivel de privilegio mayor.", - "capPe2": "Los comandos ahora corren como {{account}}: control total del host.", - "capPe3": "Terminar la sesión escalada y auditar lo que {{account}} pudo tocar.", - "titlePe": "Escalada de privilegios en {{to}} vía {{method}}", - "alertRaised": "Alerta generada", - "userExec": "Usuario abre un archivo malicioso", - "softwareDeploy": "Software enviada a un host", - "phishing": "Correo de phishing abierto", - "processInjection": "Código inyectado en un proceso", - "credDump": "Credenciales robadas", - "dataDestruction": "Datos destruidos", - "toolDownload": "Herramienta descargada y ejecutada", - "c2tunnel": "C2 a través de túnel", "scExec": "Ejecución", "scPayload": "→ payload malicioso", "capUe0": "En {{host}}{{user}}, el usuario descarga un archivo y lo abre.", @@ -6512,133 +6664,5 @@ "capCt1": "La carga se esconde en el tráfico {{proto}}.", "capCt2": "Comandos y datos cruzan la frontera sin ser vistos, montados en {{proto}}.", "capCt3": "Cortar el túnel, bloquear el extremo y revisar qué pasó por él.", - "titleCt": "{{src}} tuneliza C2 por {{proto}} hacia {{to}}", - "netPerimeter": "Perímetro", - "scDc": "Controlador de dominio", - "scObject": "Objeto modificado", - "scChangedBy": "modificado por", - "scHighRisk": "cambio de alto riesgo", - "scTktAsk": "solicitud de ticket", - "scTktUses": "reutilizado en {{n}} servicios", - "scTerminal": "Terminal", - "scRunning": "…ejecutando", - "scAmsiOff": "⚠ AMSI desactivado", - "scConn": "TCP {{port}}", - "scShellOn": "$ reverse shell", - "scHypervisor": "Hipervisor", - "scGuestVm": "máquina virtual invitada", - "scConfined": "confinado al invitado", - "scEscaped": "escapado al host", - "scBoundary": "frontera del invitado cruzada", - "scFeedAsk": "¿feed? {{ioc}}", - "scFeedBad": "MALO", - "scFeedHit": "Intel de amenazas: {{kind}}", - "scDroppedAtFw": "✕ descartado en {{fw}}", - "scTrafficStops": "el tráfico se detiene aquí", - "scSigHits": "Acertos de firma", - "capIoc0": "{{src}} se conecta a {{ioc}}.", - "capIoc1": "La inteligencia de amenazas lo marca: {{kind}}.", - "capIoc2": "{{ioc}} está en la lista de bloqueo: la conexión se corta.", - "capIoc3": "Bloquear {{ioc}} en el borde y revisar qué ya salió de la red.", - "titleIoc": "{{src}} alcanza {{ioc}} conocido", - "capPd0": "{{name}} envía una {{sig}} al perímetro.", - "capPd1": "{{fw}} coincide la firma y dispara.", - "capPd2": "El tráfico se descarta: el perímetro aguantó.", - "capPd3": "El tráfico cruza {{fw}}: la alerta es informativa.", - "capPd4": "Revisar la firma y bloquear la fuente si sigue llegando.", - "titlePd": "{{sig}} bloqueada en {{fw}}", - "capAc0": "{{who}} cambia {{what}} en {{host}}.", - "capAc1": "El {{what}} se modifica.", - "capAc2": "{{before}} → {{after}}.", - "capAc3": "Confirmar que estaba planificado o revertir el cambio de {{who}}.", - "titleAc": "{{what}} cambiado en {{host}}", - "capKb0": "{{src}} pide tickets Kerberos a {{dc}}.", - "capKb1": "El {{ticket}} que obtiene es {{kind}}.", - "capKb2": "Lo reutiliza en {{services}}: el DC lo acepta cada vez.", - "capKb3": "Resetear la contraseña krbtgt y auditar los tickets emitidos en 48 h.", - "titleKb": "{{src}} forja tickets Kerberos vía {{dc}}", - "capPs0": "En {{host}}, un script empieza con contenido codificado.", - "capPs1": "Decodifica un comando y desactiva el sensor antimalware (AMSI).", - "capPs2": "El comando decodificado se ejecuta: es un payload, no un script.", - "capPs2a": "Primero se desactiva AMSI, luego el comando codificado corre sin ser visto.", - "capPs3": "Bloquear el hash y buscar otras máquinas con el mismo script.", - "titlePs2": "Script codificado ejecutándose en {{host}}", - "capRs0": "En {{host}}, un proceso abre un socket hacia afuera.", - "capRs1": "Se conecta de vuelta a {{name}} en el puerto {{port}}: una reverse shell.", - "capRs2": "Aparece un prompt: el atacante ya puede escribir comandos en el host.", - "capRs3": "Matar la conexión, aislar {{host}} y ver qué se tecleó.", - "titleRs": "Reverse shell abierta en {{host}}", - "capVm0": "La VM invitada {{guest}} corre un proceso con acceso a nivel de host.", - "capVm1": "Intenta cruzar la frontera del hipervisor.", - "capVm2": "El proceso corre en el host {{host}}: el invitado ya no es una jaula.", - "capVm3": "Panicar el hipervisor, snapshotear al invitado y reconstruirlo.", - "titleVm": "Invitado {{guest}} escapando a {{host}}", - "listNew": "Nueva", - "newAlertsCount_one": "{{count}} nueva alerta", - "newAlertsCount_other": "{{count}} nuevas alertas", - "statTotal": "Total", - "timPage": "Página {{p}}/{{n}}", - "timPagePrev": "Página anterior", - "timPageNext": "Página siguiente", - "newAlerts": "Nuevas alertas" - }, - "scExec": "Ejecución", - "scPayload": "→ payload malicioso", - "capUe0": "En {{host}}{{user}}, el usuario descarga un archivo y lo abre.", - "capUeUser": ", {{user}}", - "capUe1": "El archivo se abre: {{file}} se confía y se ejecuta.", - "capUe2": "{{app}} inicia un proceso hijo que ejecuta {{payload}}.", - "capUe3": "Poner el archivo en cuarentena, bloquear su hash y revisar otros equipos que lo abrieron.", - "titleUe": "{{file}} abierto en {{to}}", - "scDeploy": "Despliegue", - "capSd0": "{{src}} envía software hacia {{to}} por la red.", - "capSd1": "Usa {{tool}}: un canal que instala sin interacción del usuario.", - "capSd2": "El paquete se instala en {{to}} y arranca con él.", - "capSd3": "Detener el despliegue, eliminar el componente instalado y auditar qué hizo.", - "titleSd": "Software desplegada de {{src}} a {{to}}", - "scAttachment": "adjunto abierto", - "capPh0": "{{name}} envía un correo de phishing a la empresa.", - "capPh1": "El mensaje llega a la bandeja de {{user}} y se abre.", - "capPh2": "El adjunto se ejecuta: {{file}} corre en la máquina.", - "capPh3": "Poner el correo en cuarentena, bloquear el remitente y quitar {{file}} de la máquina de {{user}}.", - "titlePh": "Correo de phishing abierto por {{user}} (de {{from}})", - "scInject": "Inyección", - "scInside": "— código dentro de un proceso confiable", - "capPi0": "En {{host}}, arranca el cargador del atacante: {{injector}}.", - "capPi1": "Inyecta código en un proceso confiable: {{victim}}.", - "capPi2": "{{victim}} ahora ejecuta el código del atacante con sus propios privilegios.", - "capPi3": "Matar el código inyectado, quitar el cargador y buscar otras víctimas.", - "titlePi": "{{injector}} inyecta código en {{victim}}", - "scCred": "Almacén de credenciales", - "scSecrets": "{{n}} secretos", - "scSecret": "secreto", - "scStolen": "✕ credenciales robadas", - "capCd0": "En {{host}}, una herramienta empieza a leer el almacén de credenciales.", - "capCd1": "Abre {{store}} y extrae el material almacenado.", - "capCd2": "Se capturan {{n}} credenciales: cuentas, claves y hashes.", - "capCd3": "Rotar todas las credenciales del almacén y buscar la herramienta de volcado.", - "titleCd": "{{store}} volcado en {{host}}", - "scData": "Datos", - "scDataItem": "datos-{{i}}", - "scGone": "perdido", - "scNoRecovery": "datos destruidos", - "capDd0": "En {{host}}, algo empieza a borrar datos en vez de cifrarlos.", - "capDd1": "{{n}} conjuntos de datos se destruyen uno tras otro.", - "capDd2": "Los datos se borran a secas: sin nota, sin rescate, sin vuelta.", - "capDd3": "Detener el proceso de origen y restaurar lo que queda desde copias fuera de línea.", - "titleDd": "Datos destruidos en {{host}}", - "scDownload": "bytes", - "scExecuted": "ejecutado", - "capTd0": "{{src}} sirve una herramienta a {{to}}.", - "capTd1": "Se descarga en una carpeta escribible: {{folder}}.", - "capTd2": "El archivo se ejecuta: {{tool}} ahora corre.", - "capTd3": "Eliminar la herramienta, bloquear su hash y revisar qué hosts la ejecutaron.", - "titleTd": "{{src}} deja una herramienta en {{to}}", - "scTunnel": "oculto en tráfico {{proto}}", - "scTunneled": "Bytes tunelados", - "capCt0": "{{src}} habla con {{to}} usando un protocolo que parece normal.", - "capCt1": "La carga se esconde en el tráfico {{proto}}.", - "capCt2": "Comandos y datos cruzan la frontera sin ser vistos, montados en {{proto}}.", - "capCt3": "Cortar el túnel, bloquear el extremo y revisar qué pasó por él.", - "titleCt": "{{src}} tuneliza C2 por {{proto}} hacia {{to}}" + "titleCt": "{{src}} tuneliza C2 por {{proto}} hacia {{to}}" } diff --git a/frontend/src/shared/i18n/locales/fr.json b/frontend/src/shared/i18n/locales/fr.json index a945621d3..97f4ae544 100644 --- a/frontend/src/shared/i18n/locales/fr.json +++ b/frontend/src/shared/i18n/locales/fr.json @@ -1,6459 +1,6611 @@ { - "onboarding": { - "adminEmail": { - "title": "Définir l'e-mail de l'administrateur", - "subtitle": "Requis avant de continuer", - "description": "Votre compte administrateur utilise encore l'e-mail par défaut. Définissez une adresse réelle — elle est nécessaire pour la récupération du mot de passe, les notifications et les e-mails d'alerte.", - "emailLabel": "Adresse e-mail", - "save": "Enregistrer et continuer", - "saving": "Enregistrement…", - "success": "E-mail de l'administrateur défini. Configurez ensuite votre serveur de messagerie.", - "error": "Impossible d'enregistrer votre e-mail. Veuillez réessayer." - } - }, - "common": { - "appName": "UTMStack", - "language": "Langue", - "actions": { - "save": "Enregistrer", - "cancel": "Annuler", - "retry": "Réessayer", - "refresh": "Actualiser", - "delete": "Supprimer", - "remove": "Retirer", - "close": "Fermer", - "next": "Suivant", - "back": "Retour" - }, - "confirm": { - "delete": "Supprimer", - "working": "En cours…" - }, - "dateRange": { - "pick": "Choisir une plage", - "clear": "Effacer", - "done": "OK", - "apply": "Appliquer" - }, - "loadingMore": "Chargement…", - "allLoaded": "{{count}} chargés", - "startFrom": { - "scratch": "De zéro", - "scratchHint": "Une définition vide que vous remplissez.", - "copy": "À partir d’une existante", - "copyHint": "Tout est copié sauf l’identifiant et le nom.", - "pickTitle": "Choisissez quoi copier", - "back": "Retour", - "count": "{{n}} disponibles", - "search": "Rechercher par nom", - "none": "Aucun résultat pour cette recherche" + "onboarding": { + "adminEmail": { + "title": "Définir l'e-mail de l'administrateur", + "subtitle": "Requis avant de continuer", + "description": "Votre compte administrateur utilise encore l'e-mail par défaut. Définissez une adresse réelle — elle est nécessaire pour la récupération du mot de passe, les notifications et les e-mails d'alerte.", + "emailLabel": "Adresse e-mail", + "save": "Enregistrer et continuer", + "saving": "Enregistrement…", + "success": "E-mail de l'administrateur défini. Configurez ensuite votre serveur de messagerie.", + "error": "Impossible d'enregistrer votre e-mail. Veuillez réessayer." + } }, - "cancel": "Annuler" - }, - "auth": { - "login": { - "title": "Bon retour", - "subtitle": "Connectez-vous pour continuer sur {{brand}}", - "loginLabel": "E-mail", - "passwordLabel": "Mot de passe", - "forgot": "Oublié ?", - "submit": "Se connecter", - "terms": "En vous connectant, vous acceptez les conditions de service de {{brand}}.", - "orContinueWith": "ou continuer avec", - "continueWith": "Continuer avec {{name}}", - "signingInTo": "Connexion à {{name}}", - "useAnother": "En utiliser un autre" + "common": { + "appName": "UTMStack", + "language": "Langue", + "actions": { + "save": "Enregistrer", + "cancel": "Annuler", + "retry": "Réessayer", + "refresh": "Actualiser", + "delete": "Supprimer", + "remove": "Retirer", + "close": "Fermer", + "next": "Suivant", + "back": "Retour" + }, + "confirm": { + "delete": "Supprimer", + "working": "En cours…" + }, + "dateRange": { + "pick": "Choisir une plage", + "clear": "Effacer", + "done": "OK", + "apply": "Appliquer" + }, + "loadingMore": "Chargement…", + "allLoaded": "{{count}} chargés", + "startFrom": { + "scratch": "De zéro", + "scratchHint": "Une définition vide que vous remplissez.", + "copy": "À partir d’une existante", + "copyHint": "Tout est copié sauf l’identifiant et le nom.", + "pickTitle": "Choisissez quoi copier", + "back": "Retour", + "count": "{{n}} disponibles", + "search": "Rechercher par nom", + "none": "Aucun résultat pour cette recherche" + }, + "cancel": "Annuler" + }, + "auth": { + "login": { + "title": "Bon retour", + "subtitle": "Connectez-vous pour continuer sur {{brand}}", + "loginLabel": "E-mail", + "passwordLabel": "Mot de passe", + "forgot": "Oublié ?", + "submit": "Se connecter", + "terms": "En vous connectant, vous acceptez les conditions de service de {{brand}}.", + "orContinueWith": "ou continuer avec", + "continueWith": "Continuer avec {{name}}", + "signingInTo": "Connexion à {{name}}", + "useAnother": "En utiliser un autre" + }, + "tfa": { + "title": "Vérification en deux étapes", + "subtitleTotp": "Saisissez le code à 6 chiffres de votre application d'authentification.", + "subtitleEmail": "Saisissez le code à 6 chiffres que nous vous avons envoyé par e-mail.", + "codeLabel": "Code de vérification", + "submit": "Vérifier", + "back": "Retour à la connexion" + }, + "forgot": { + "title": "Réinitialiser le mot de passe", + "subtitle": "Nous vous enverrons un lien par e-mail pour définir un nouveau mot de passe.", + "emailLabel": "E-mail", + "submit": "Envoyer le lien", + "sent": "Si cet e-mail est enregistré, un lien de réinitialisation est en route." + }, + "errors": { + "tooManyAttempts": "Trop de tentatives. Réessayez dans quelques minutes.", + "deactivated": "Ce compte est désactivé.", + "invalidCredentials": "Identifiants invalides.", + "codeExpired": "Ce code a expiré. Reconnectez-vous.", + "loginFailed": "Échec de la connexion. Veuillez réessayer.", + "invalidCode": "Code invalide ou expiré.", + "verifyFailed": "Échec de la vérification. Veuillez réessayer.", + "resetFailed": "Impossible d'envoyer l'e-mail de réinitialisation. Veuillez réessayer.", + "ssoFailed": "L'authentification unique n'a pas abouti. Réessayez ou utilisez votre mot de passe." + } }, - "tfa": { - "title": "Vérification en deux étapes", - "subtitleTotp": "Saisissez le code à 6 chiffres de votre application d'authentification.", - "subtitleEmail": "Saisissez le code à 6 chiffres que nous vous avons envoyé par e-mail.", - "codeLabel": "Code de vérification", - "submit": "Vérifier", - "back": "Retour à la connexion" + "profile": { + "hero": { + "administrator": "Administrateur", + "changeAvatar": "Changer l'avatar", + "removeAvatar": "Supprimer l'avatar" + }, + "personal": { + "title": "Informations personnelles", + "description": "Mettez à jour votre nom et vos coordonnées.", + "firstName": "Prénom", + "lastName": "Nom", + "email": "E-mail", + "language": "Langue", + "languageHint": "Utilisée pour l'interface du panneau.", + "systemDefault": "Par défaut du système", + "username": "Nom d'utilisateur", + "usernameHint": "Le nom d'utilisateur ne peut pas être modifié.", + "reset": "Réinitialiser", + "save": "Enregistrer", + "saving": "Enregistrement…", + "name": "Nom" + }, + "password": { + "title": "Mot de passe", + "description": "Utilisez un mot de passe fort que vous ne réutilisez nulle part ailleurs.", + "current": "Mot de passe actuel", + "new": "Nouveau mot de passe", + "newHint": "Au moins 8 caractères.", + "confirm": "Confirmer le nouveau mot de passe", + "update": "Mettre à jour le mot de passe", + "updating": "Mise à jour…" + }, + "sessions": { + "title": "Sessions actives", + "description": "Appareils actuellement connectés à votre compte.", + "loading": "Chargement des sessions…", + "empty": "Aucune session active.", + "thisDevice": "Cet appareil", + "unknownIp": "IP inconnue", + "unknownDevice": "Appareil inconnu", + "deviceLabel": "{{browser}} sur {{os}}", + "signedIn": "Connecté {{time}}", + "revoke": "Révoquer", + "revoking": "Révocation…", + "signOutOthers": "Déconnecter toutes les autres sessions", + "signingOut": "Déconnexion…" + }, + "tfa": { + "title": "Authentification à deux facteurs", + "description": "Ajoutez une couche de sécurité supplémentaire à votre compte.", + "loading": "Chargement…", + "methodTotp": "Application d'authentification", + "methodEmail": "Code par e-mail", + "onTitle": "L'authentification à deux facteurs est activée", + "method": "Méthode : {{method}}", + "configured": "Configuré", + "disable": "Désactiver", + "disableTitle": "Désactiver l'authentification à deux facteurs", + "disableDescription": "Saisissez votre mot de passe actuel pour confirmer. Votre compte ne reposera plus que sur le mot de passe.", + "currentPasswordPlaceholder": "Mot de passe actuel", + "disableConfirm": "Désactiver le 2FA", + "disabling": "Désactivation…", + "offTitle": "L'authentification à deux facteurs est désactivée", + "status": "Statut :", + "notConfigured": "Non configuré", + "enable": "Activer", + "chooseMethod": "Choisissez une méthode", + "totpDesc": "Utilisez Google Authenticator, 1Password, etc. Recommandé.", + "emailDesc": "Recevez un code à 6 chiffres par e-mail à la connexion.", + "noEmailHint": "Ajoutez un e-mail à votre profil pour utiliser la méthode par e-mail.", + "continue": "Continuer", + "starting": "Démarrage…", + "scanTitle": "Scannez le code QR", + "scanDescription": "Scannez-le avec votre application d'authentification, puis saisissez le code à 6 chiffres affiché.", + "manualKey": "Ou saisissez cette clé manuellement :", + "checkEmailTitle": "Vérifiez votre e-mail", + "checkEmailDescription": "Nous avons envoyé un code à 6 chiffres à {{email}}. Saisissez-le ci-dessous.", + "resend": "Renvoyer", + "verifyEnable": "Vérifier et activer", + "verifying": "Vérification…" + }, + "actions": { + "cancel": "Annuler" + }, + "toast": { + "profileUpdated": "Profil mis à jour", + "emailInUse": "Cet e-mail est déjà utilisé", + "profileUpdateFailed": "Impossible de mettre à jour le profil", + "passwordsNoMatch": "Les mots de passe ne correspondent pas", + "passwordTooShort": "Le mot de passe doit comporter au moins 8 caractères", + "passwordChanged": "Mot de passe modifié — les autres sessions ont été déconnectées", + "currentPasswordWrong": "Le mot de passe actuel est incorrect", + "passwordChangeFailed": "Impossible de modifier le mot de passe", + "avatarTypeNotAllowed": "Type d'image non autorisé (utilisez PNG, JPEG, WEBP ou GIF)", + "avatarTooLarge": "L'image est trop volumineuse (max 2 Mo)", + "avatarUpdated": "Avatar mis à jour", + "avatarUploadFailed": "Impossible d'envoyer l'avatar", + "avatarRemoved": "Avatar supprimé", + "avatarRemoveFailed": "Impossible de supprimer l'avatar", + "sessionsLoadFailed": "Impossible de charger les sessions", + "sessionRevoked": "Session révoquée", + "sessionRevokeFailed": "Impossible de révoquer la session", + "othersSignedOut": "Autres sessions déconnectées", + "othersRevokeFailed": "Impossible de révoquer les sessions", + "tfaEmailCodeSent": "Nous avons envoyé un code à 6 chiffres à votre e-mail", + "tfaNewCodeSent": "Un nouveau code a été envoyé", + "tfaWaitResend": "Veuillez patienter avant de demander un nouveau code", + "tfaResendFailed": "Impossible de renvoyer le code", + "tfaEnterCode": "Saisissez le code à 6 chiffres", + "tfaEnabled": "Authentification à deux facteurs activée", + "tfaEnterPassword": "Saisissez votre mot de passe actuel", + "tfaDisabled": "Authentification à deux facteurs désactivée", + "tfaDisableFailed": "Impossible de désactiver le 2FA", + "tfaInvalidCode": "Code invalide ou expiré", + "tfaAlreadyEnabled": "Le 2FA est déjà activé", + "tfaTooManyRequests": "Trop de requêtes ; réessayez bientôt", + "tfaVerifyFailed": "Impossible de vérifier le code", + "genericError": "Une erreur s'est produite", + "tfaMailUnavailable": "Le second facteur par e-mail nécessite un serveur de messagerie. Configurez-le dans Paramètres → Configuration de l'e-mail." + } }, - "forgot": { - "title": "Réinitialiser le mot de passe", - "subtitle": "Nous vous enverrons un lien par e-mail pour définir un nouveau mot de passe.", - "emailLabel": "E-mail", - "submit": "Envoyer le lien", - "sent": "Si cet e-mail est enregistré, un lien de réinitialisation est en route." + "home": { + "hero": { + "title": "Que souhaitez-vous savoir à partir de vos données de sécurité ?", + "placeholder": "Renseignez-vous sur Scattered Spider, cela nous concerne-t-il ?, avons-nous déjà été touchés ?, créez une règle de détection et maintenez-la à jour.", + "send": "Envoyer", + "suggestions": { + "threatHunt": "Chasse aux menaces", + "observableTriage": "Triage des observables", + "writeRule": "Écrire une règle", + "systemStatus": "État actuel du système" + } + }, + "kpis": { + "alerts24h": "Alertes (24 h)", + "openIncidents": "Incidents ouverts", + "openIncidentsSub": "actuellement ouverts", + "highSeverity24h": "Gravité élevée (24 h)", + "highSeveritySub": "sur {{n}} alertes", + "activePlaybooks": "Playbooks actifs", + "activePlaybooksSub": "activés" + }, + "datasources": { + "title": "Sources de données", + "viewAll": "Tout voir", + "ofTotal": "sur {{n}}", + "datasources": "sources de données", + "sendingData": "envoient des données", + "totalEvents": "Total des événements", + "noData": "Aucune donnée d'ingestion sur cette période" + }, + "span": { + "recent": "période récente", + "days_one": "{{count}} dernier jour", + "days_other": "{{count}} derniers jours", + "hours": "dernières {{n}} h" + }, + "mitre": { + "title": "Principales techniques MITRE ATT&CK", + "explore": "Explorer", + "empty": "Aucune alerte avec technique attribuée pour le moment" + }, + "assets": { + "title": "Actifs les plus ciblés", + "viewAll": "Tout voir", + "asset": "Actif", + "alerts": "Alertes", + "empty": "Aucun actif ciblé dans les alertes récentes" + }, + "compliance": { + "title": "Score de conformité", + "reports": "Rapports", + "empty": "Aucun rapport de conformité généré pour le moment" + }, + "health": { + "title": "État du système", + "details": "Détails", + "services": { + "backend": "API backend", + "opensearch": "Cluster OpenSearch", + "socai": "Moteur SOC-AI" + }, + "detail": { + "noClusterInfo": "aucune information sur le cluster", + "disabled": "désactivé", + "tools": "{{n}} outils", + "unreachable": "injoignable", + "pending": "…" + } + } }, - "errors": { - "tooManyAttempts": "Trop de tentatives. Réessayez dans quelques minutes.", - "deactivated": "Ce compte est désactivé.", - "invalidCredentials": "Identifiants invalides.", - "codeExpired": "Ce code a expiré. Reconnectez-vous.", - "loginFailed": "Échec de la connexion. Veuillez réessayer.", - "invalidCode": "Code invalide ou expiré.", - "verifyFailed": "Échec de la vérification. Veuillez réessayer.", - "resetFailed": "Impossible d'envoyer l'e-mail de réinitialisation. Veuillez réessayer.", - "ssoFailed": "L'authentification unique n'a pas abouti. Réessayez ou utilisez votre mot de passe." - } - }, - "profile": { - "hero": { - "administrator": "Administrateur", - "changeAvatar": "Changer l'avatar", - "removeAvatar": "Supprimer l'avatar" + "nav": { + "home": "Accueil", + "dashboards": "Tableaux de bord", + "dashboardList": "Liste des tableaux", + "visualizationList": "Widgets", + "newDashboard": "Nouveau tableau", + "newVisualization": "Nouveau widget", + "threatManagement": "Gestion des menaces", + "alerts": "Alertes", + "incidents": "Incidents", + "adversaryView": "Vue des adversaires", + "soar": "SOAR", + "flows": "Flux", + "executionHistory": "Historique d'exécutions", + "interactiveConsole": "Console interactive", + "logExplorer": "Explorateur de logs", + "userAuditor": "Auditeur d'utilisateurs", + "threatIntelligence": "Renseignement sur les menaces", + "threat-intel": { + "indicators": "Indicateurs", + "analyzt": "Analyste IA", + "triage": "Triage", + "report": "Rapport" + }, + "compliance": "Conformité", + "configure": "Configurer", + "dataSources": "Sources de données", + "integrations": "Intégrations", + "alertingRules": "Règles d'alerte", + "dataProcessing": "Traitement des données", + "team": "Équipe", + "settings": "Paramètres", + "back": "Retour", + "regexPatterns": "Expressions régulières", + "taggingRules": "Règles d'étiquetage", + "parsingFilters": "Pipelines", + "overview": "Vue d'ensemble", + "tenants": "Locataires", + "openMenu": "Ouvrir le menu", + "closeMenu": "Fermer le menu", + "liveOps": "Opérations en direct" + }, + "dashboards": { + "title": "Tableaux de bord", + "subtitle": "Parcourez et modifiez des tableaux de bord interactifs.", + "list": { + "title": "Tableaux de bord", + "create": "Nouveau", + "searchPlaceholder": "Rechercher des tableaux de bord…", + "loading": "Chargement des tableaux de bord…", + "empty": "Aucun tableau de bord pour le moment.", + "rename": "Renommer", + "delete": "Supprimer" + }, + "actions": { + "edit": "Modifier", + "editWithAi": "Modifier avec l'IA" + }, + "refresh": { + "title": "Actualisation automatique", + "options": { + "off": "Désactivé", + "10s": "10s", + "30s": "30s", + "1m": "1m", + "5m": "5m", + "15m": "15m" + } + }, + "editor": { + "editing": "Édition", + "addWidget": "Ajouter un widget", + "save": "Enregistrer", + "discard": "Annuler", + "newTitle": "Nouveau widget", + "newSubtitle": "Choisissez un type de graphique, une source de données et mettez-le en forme visuellement. La requête SQL est générée automatiquement.", + "editTitle": "Modifier le widget", + "editSubtitle": "Ajustez la définition du graphique. Les modifications s'appliquent partout où ce widget est utilisé.", + "loading": "Chargement du widget…", + "notFoundTitle": "Widget introuvable", + "notFoundSubtitle": "Elle a peut-être été supprimée ou vous n'y avez pas accès.", + "backToDashboard": "Retour au tableau de bord", + "chartType": { + "title": "Type de graphique" + }, + "chartTypes": { + "bar": { + "label": "Barres", + "description": "Comparer des valeurs entre catégories." + }, + "line": { + "label": "Courbe", + "description": "Tendances sur un axe ordonné." + }, + "area": { + "label": "Aire", + "description": "Courbe remplie — met en valeur le volume." + }, + "pie": { + "label": "Camembert", + "description": "Part d'un total par catégorie." + }, + "metric": { + "label": "Métrique", + "description": "Une valeur scalaire unique." + }, + "table": { + "label": "Tableau", + "description": "Lignes agrégées." + }, + "list": { + "label": "Liste", + "description": "Lignes brutes, sans agrégation." + }, + "region_map": { + "label": "Carte de coordonnées", + "description": "Placer des marqueurs sur une carte du monde à partir de coordonnées lat/lon." + }, + "text": { + "label": "Texte", + "description": "Texte libre ou sortie ligne par ligne." + } + }, + "dataSource": { + "title": "Quelles données ?", + "dataset": "Jeu de données", + "noDatasetHint": "Choisissez un jeu de données pour activer les conditions et le regroupement." + }, + "widgetTitle": { + "label": "Titre", + "placeholder": "Facultatif — par défaut, le type de graphique" + }, + "dataset": { + "placeholder": "Sélectionnez un jeu de données…", + "loading": "Chargement des jeux de données…" + }, + "filters": { + "title": "Inclure uniquement les événements où…", + "empty": "Aucune condition — tous les événements de la plage horaire sont inclus.", + "add": "Ajouter une condition", + "remove": "Retirer", + "field": "Champ", + "fieldPlaceholder": "ex. host.name", + "operator": "Opérateur", + "value": "Valeur", + "valuePlaceholder": "Valeur", + "from": "De", + "to": "À", + "noValue": "Aucune valeur requise", + "listPlaceholder": "Valeurs séparées par des virgules" + }, + "operators": { + "IS": "est", + "IS_NOT": "n'est pas", + "IS_ONE_OF_TERMS": "est l'un de", + "IS_GREATER_THAN": "est supérieur à", + "IS_LESS_THAN_OR_EQUALS": "est inférieur ou égal à", + "IS_BETWEEN": "est entre", + "CONTAIN": "contient", + "DOES_NOT_CONTAIN": "ne contient pas", + "START_WITH": "commence par", + "ENDS_WITH": "se termine par", + "EXIST": "existe", + "DOES_NOT_EXIST": "n'existe pas" + }, + "dimension": { + "title": "Regrouper par", + "field": "Champ", + "placeholder": "Choisissez un champ à regrouper…" + }, + "table": { + "hint": "Affiche tous les champs des enregistrements. Ajoutez des colonnes pour en choisir.", + "columnsTitle": "Colonnes", + "allColumns": "Toutes les colonnes seront affichées. Ajoutez des champs pour en choisir certaines.", + "addColumn": "Ajouter une colonne…", + "removeColumn": "Retirer la colonne" + }, + "chartPreview": { + "title": "Aperçu du graphique", + "noQuery": "Choisissez un jeu de données pour voir un aperçu.", + "error": "La requête d'aperçu a échoué." + }, + "chartTypeChip": { + "label": "Graphique :" + }, + "chartTypeModal": { + "title": "Choisir un type de graphique", + "subtitle": "Choisissez comment visualiser les données. Vous pourrez le modifier plus tard.", + "confirm": "Continuer", + "swapTitle": "Changer le type de graphique", + "swapConfirm": "Appliquer" + }, + "saveVisualization": "Enregistrer le widget", + "fieldSelect": { + "loading": "Chargement des champs…", + "choose": "Choisissez un champ…" + }, + "toast": { + "notReady": "Choisissez un jeu de données et un champ de répartition avant d’enregistrer." + }, + "breakdown": { + "title": "Répartir par", + "topValuesTable": "Tableau des valeurs principales", + "time": "Dans le temps", + "field": "Valeurs les plus fréquentes", + "interval": "Taille de l'intervalle", + "intervalAuto": "Automatique", + "limit": "Combien", + "limitPlaceholder": "Par défaut (50)", + "splitHint": "Facultatif : une ligne par valeur de ce champ." + }, + "editFilters": "Edit filters" + }, + "grid": { + "empty": "Ce tableau de bord ne contient encore aucun widget.", + "missingVisualization": "Widget indisponible", + "unknownVisualization": "Widget" + }, + "widget": { + "renderError": "Impossible d'afficher ce widget.", + "count": "Nombre", + "loading": "Chargement des données…", + "queryError": "Impossible de charger les données du widget.", + "noData": "Aucune donnée pour la plage de temps sélectionnée.", + "regionMapEmpty": "Aucun point avec lat/lon valides.", + "regionMapShapeHint": "Le SQL doit renvoyer des colonnes de latitude et de longitude (ou un tableau value [lat, lon, count]).", + "regionMapUnnamed": "(sans nom)", + "regionMapValue": "valeur : {{value}}", + "editAriaLabel": "Modifier le widget", + "removeAriaLabel": "Retirer le widget", + "moveBack": "Reculer", + "moveForward": "Avancer", + "width": "Largeur", + "height": "Hauteur", + "widthSmall": "1 col", + "widthMedium": "2 cols", + "widthLarge": "3 cols", + "heightNormal": "Normale", + "heightTall": "Haute", + "incompleteSpec": "Il manque une partie de la question de ce widget." + }, + "form": { + "createTitle": "Nouveau tableau de bord", + "renameTitle": "Modifier le tableau de bord", + "name": "Nom", + "namePlaceholder": "ex. Vue d'ensemble du réseau", + "description": "Description", + "descriptionPlaceholder": "Facultatif", + "cancel": "Annuler", + "create": "Créer", + "save": "Enregistrer" + }, + "confirm": { + "deleteTitle": "Supprimer le tableau de bord", + "delete": "Supprimer le tableau de bord « {{name}} » ? Cette action est irréversible.", + "deleteWidgetsTitle": "Supprimer les widgets", + "deleteWidgets_one": "Supprimer ce widget ? Cette action est irréversible.", + "deleteWidgets_other": "Supprimer {{count}} widgets ? Cette action est irréversible.", + "dismissTitle": "Retirer le tableau de bord", + "dismiss": "Supprimer le tableau de bord par défaut « {{name}} » ? Vous pourrez en créer un nouveau à partir de celui-ci avec « Nouveau » → « À partir d'une existante »." + }, + "page": { + "noSelection": "Choisissez un tableau de bord dans la liste ou créez-en un pour commencer.", + "loading": "Chargement des widgets…" + }, + "toast": { + "created": "Tableau de bord créé.", + "createFailed": "Impossible de créer le tableau de bord.", + "updated": "Tableau de bord mis à jour.", + "updateFailed": "Impossible de mettre à jour le tableau de bord.", + "deleted": "Tableau de bord supprimé.", + "deleteFailed": "Impossible de supprimer le tableau de bord.", + "layoutSaved": "Disposition enregistrée.", + "layoutSaveFailed": "Impossible d'enregistrer la disposition.", + "visualizationCreated": "Widget créé.", + "visualizationCreateFailed": "Impossible de créer le widget.", + "visualizationUpdated": "Widget mis à jour.", + "visualizationUpdateFailed": "Impossible de mettre à jour le widget.", + "visualizationDeleted": "Widget supprimé.", + "visualizationDeleteFailed": "Impossible de supprimer le widget.", + "filterCreated": "Filtre créé.", + "filterUpdated": "Filtre mis à jour.", + "filterDeleted": "Filtre supprimé.", + "filterCreateFailed": "Echec de la creation du filtre.", + "filterUpdateFailed": "Echec de la mise a jour du filtre.", + "filterDeleteFailed": "Echec de la suppression du filtre.", + "filtersSaved": "Filters saved.", + "filtersSaveFailed": "Could not save filters." + }, + "newDashboard": { + "title": "Nouveau tableau de bord", + "subtitle": "Créez un tableau de bord vide. Vous pourrez ajouter des widgets après l'avoir enregistré.", + "modeManual": "Créer manuellement", + "modeAi": "Avec l'IA", + "aiLocked": "Activez SOC-AI et configurez-le pour utiliser cette fonction.", + "aiDescriptionLabel": "Que doit afficher ce tableau de bord ?", + "aiDescriptionPlaceholder": "ex. Connexions échouées par pays, 7 derniers jours", + "aiCreate": "Créer avec l'IA", + "aiOpenerWithDetails": "Créez un tableau de bord nommé « {{name}} » affichant : {{description}}" + }, + "newVisualization": { + "title": "Nouveau widget", + "subtitle": "Définissez un graphique réutilisable à partir d'une requête SQL et d'une configuration ECharts.", + "sqlQuery": "Requête SQL", + "sqlQueryPlaceholder": "SELECT bucket, count(*) FROM logs GROUP BY bucket", + "sqlQueryHint": "Utilisez les marqueurs timeFilter, from et to (entre doubles accolades) pour appliquer le sélecteur de temps au rendu.", + "config": "Configuration du graphique (option ECharts, JSON)", + "configHint": "Doit être du JSON valide. Les lignes du SQL sont exposées via `dataset.source` — connectez vos séries avec `encode`.", + "configError": "JSON non valide : {{error}}" + }, + "visualizationList": { + "title": "Widgets", + "subtitle": "{{count}} widget(s) disponible(s).", + "subtitleFiltered": "{{shown}} sur {{total}} affichées.", + "create": "Nouvelle", + "searchPlaceholder": "Rechercher des widgets…", + "loading": "Chargement des widgets…", + "empty": "Aucun widget pour le moment.", + "emptyFiltered": "Aucun widget ne correspond aux filtres actuels.", + "delete": "Supprimer", + "deleteTitle": "Supprimer le widget", + "confirmDelete": "Supprimer le widget « {{name}} » ? Cette action est irréversible.", + "filters": { + "search": "Recherche", + "chartType": "Type de graphique", + "allChartTypes": "Tous les types de graphique", + "source": "Source", + "allSources": "Toutes les sources", + "createdAt": "Créée", + "modifiedAt": "Modifiée", + "createdRangeTitle": "Plage personnalisée — Création", + "modifiedRangeTitle": "Plage personnalisée — Modification", + "pickRange": "Choisir une plage", + "datePresets": { + "all": "Toute la période", + "today": "Aujourd'hui", + "last7": "7 derniers jours", + "last30": "30 derniers jours", + "lastYear": "Année dernière", + "custom": "Plage personnalisée" + }, + "clear": "Réinitialiser les filtres" + }, + "col": { + "name": "Nom", + "chartType": "Type de graphique", + "source": "Source", + "description": "Description", + "created": "Créée", + "modified": "Modifiée" + } + }, + "tabs": { + "dashboards": "Tableaux de bord", + "visualizations": "Widgets", + "newDashboard": "Nouveau tableau de bord", + "unsetDefault": "Retirer par défaut", + "options": "Options" + }, + "picker": { + "none": "Sélectionner un tableau de bord", + "search": "Rechercher des tableaux de bord…", + "new": "Nouveau tableau de bord", + "setDefault": "Définir par défaut", + "empty": "Aucun tableau de bord" + }, + "empty": { + "title": "Aucun tableau de bord", + "body": "Créez votre premier tableau de bord pour voir vos données de sécurité d'un coup d'œil.", + "cta": "Créer un tableau de bord" + }, + "filters": { + "addTitle": "Ajouter un filtre", + "editTitle": "Modifier le filtre", + "removeTitle": "Supprimer le filtre", + "removeConfirm": "Supprimer le filtre « {{label}} » ? Cette action est irréversible.", + "remove": "Supprimer", + "editAria": "Modifier le filtre", + "removeAria": "Supprimer le filtre", + "saving": "Enregistrement…", + "addChip": "Ajouter un filtre", + "chooseValue": "Choose…", + "selected": "selected", + "loading": "Loading values…", + "searchPlaceholder": "Search values…", + "noValues": "No values available.", + "loadError": "Could not load values.", + "clear": "Clear", + "editorTitle": "Dashboard filters", + "editorHint": "Add dropdown chips that filter every widget on this dashboard.", + "emptyEditor": "No filter chips yet. Add one to get started.", + "cancel": "Cancel", + "save": "Save", + "field": { + "dataset": "Data set", + "field": "Field", + "chooseField": "Choose a field…", + "label": "Label", + "labelPlaceholder": "e.g. Host", + "placeholder": "Placeholder", + "placeholderPlaceholder": "e.g. Pick a host", + "multiple": "Multiple", + "searchable": "Searchable" + } + }, + "duplicate": { + "copyName": "{{name}} (copie)" + } }, - "personal": { - "title": "Informations personnelles", - "description": "Mettez à jour votre nom et vos coordonnées.", - "firstName": "Prénom", - "lastName": "Nom", - "email": "E-mail", - "language": "Langue", - "languageHint": "Utilisée pour l'interface du panneau.", - "systemDefault": "Par défaut du système", - "username": "Nom d'utilisateur", - "usernameHint": "Le nom d'utilisateur ne peut pas être modifié.", - "reset": "Réinitialiser", - "save": "Enregistrer", - "saving": "Enregistrement…", - "name": "Nom" + "settings": { + "title": "Paramètres", + "license": "Licence", + "notifications": "Notifications", + "connectionKey": "Clé de connexion", + "dataRetention": "Rétention des données", + "indices": "Index", + "theme": "Thème", + "branding": "Marque", + "apiKeys": "Clés API", + "identityProviders": "Fournisseurs d'identité", + "email": "Configuration e-mail", + "dateFormat": "Format de date", + "language": "Langue", + "auditLogs": "Journaux d'audit", + "about": "À propos", + "socAi": "SOC-AI", + "supportAccess": "Accès support", + "threatwinds": "Intégration ThreatWinds" + }, + "topbar": { + "theme": { + "light": "Mode clair", + "dark": "Mode sombre" + }, + "manageLicense": "Gérer la licence", + "profile": { + "profile": "Profil", + "license": "Licence", + "logout": "Se déconnecter" + } }, - "password": { - "title": "Mot de passe", - "description": "Utilisez un mot de passe fort que vous ne réutilisez nulle part ailleurs.", - "current": "Mot de passe actuel", - "new": "Nouveau mot de passe", - "newHint": "Au moins 8 caractères.", - "confirm": "Confirmer le nouveau mot de passe", - "update": "Mettre à jour le mot de passe", - "updating": "Mise à jour…" + "notifications": { + "title": "Notifications", + "markAllRead": "Tout marquer comme lu", + "empty": "Vous n'avez aucune notification.", + "viewAll": "Voir tout", + "markRead": "Marquer comme lu", + "markUnread": "Marquer comme non lu", + "delete": "Supprimer", + "subtitle": "{{total}} au total · {{unread}} non lues", + "allCaughtUp": "Tout est à jour.", + "loadFailed": "Impossible de charger les notifications." }, - "sessions": { - "title": "Sessions actives", - "description": "Appareils actuellement connectés à votre compte.", - "loading": "Chargement des sessions…", - "empty": "Aucune session active.", - "thisDevice": "Cet appareil", - "unknownIp": "IP inconnue", - "unknownDevice": "Appareil inconnu", - "deviceLabel": "{{browser}} sur {{os}}", - "signedIn": "Connecté {{time}}", - "revoke": "Révoquer", - "revoking": "Révocation…", - "signOutOthers": "Déconnecter toutes les autres sessions", - "signingOut": "Déconnexion…" + "pagination": { + "perPage": "Par page", + "pageOf": "Page {{page}} sur {{total}}", + "previous": "Précédent", + "next": "Suivant" }, - "tfa": { - "title": "Authentification à deux facteurs", - "description": "Ajoutez une couche de sécurité supplémentaire à votre compte.", - "loading": "Chargement…", - "methodTotp": "Application d'authentification", - "methodEmail": "Code par e-mail", - "onTitle": "L'authentification à deux facteurs est activée", - "method": "Méthode : {{method}}", - "configured": "Configuré", - "disable": "Désactiver", - "disableTitle": "Désactiver l'authentification à deux facteurs", - "disableDescription": "Saisissez votre mot de passe actuel pour confirmer. Votre compte ne reposera plus que sur le mot de passe.", - "currentPasswordPlaceholder": "Mot de passe actuel", - "disableConfirm": "Désactiver le 2FA", - "disabling": "Désactivation…", - "offTitle": "L'authentification à deux facteurs est désactivée", - "status": "Statut :", - "notConfigured": "Non configuré", - "enable": "Activer", - "chooseMethod": "Choisissez une méthode", - "totpDesc": "Utilisez Google Authenticator, 1Password, etc. Recommandé.", - "emailDesc": "Recevez un code à 6 chiffres par e-mail à la connexion.", - "noEmailHint": "Ajoutez un e-mail à votre profil pour utiliser la méthode par e-mail.", - "continue": "Continuer", - "starting": "Démarrage…", - "scanTitle": "Scannez le code QR", - "scanDescription": "Scannez-le avec votre application d'authentification, puis saisissez le code à 6 chiffres affiché.", - "manualKey": "Ou saisissez cette clé manuellement :", - "checkEmailTitle": "Vérifiez votre e-mail", - "checkEmailDescription": "Nous avons envoyé un code à 6 chiffres à {{email}}. Saisissez-le ci-dessous.", - "resend": "Renvoyer", - "verifyEnable": "Vérifier et activer", - "verifying": "Vérification…" + "license": { + "title": "Licence", + "subtitle": "Votre édition, vos fonctionnalités et votre fichier de licence.", + "loading": "Chargement de la licence…", + "loadError": "Impossible de charger les informations de licence.", + "statusLabel": "Statut", + "status": { + "community": "Community", + "active": "Active", + "expiring": "Bientôt expirée", + "expired": "Expirée" + }, + "edition": "Édition", + "enterprise": "Enterprise", + "community": "Community", + "editionLine": "Édition {{edition}}", + "datasourceLimit": "Limite de sources de données", + "unlimited": "Illimité", + "mssp": "MSSP / multi-locataire", + "enabled": "Activé", + "licenseType": "Type de licence", + "instanceId": "ID d'instance", + "enterpriseUnlocked": "Fonctionnalités Enterprise débloquées", + "validUntil": "Valable jusqu'au", + "noExpiry": "Pas d'expiration", + "timeRemaining": "Temps restant", + "expiredAgo": "Expirée il y a {{days}}j", + "daysShort": "{{days}}j", + "msspShort": "MSSP", + "communityEdition": "Édition Community", + "communityBlurb": "Gratuite et open source. Téléchargez une licence Enterprise ci-dessous pour débloquer le multi-locataire, le SSO, des limites de sources de données plus élevées et la conformité avancée.", + "upgrade": "Passer à Enterprise", + "uploadTitle": "Télécharger une licence", + "uploadBlurb": "Installez ou remplacez le fichier LICENSE signé. Le serveur valide la signature et l'expiration avant de l'appliquer. Admin uniquement.", + "installLicense": "Installer la licence", + "chooseFile": "Choisir un fichier", + "noFileSelected": "Aucun fichier sélectionné", + "toast": { + "installed": "Licence installée — édition {{edition}}.", + "adminRequired": "Des privilèges d'administrateur sont requis pour télécharger une licence.", + "invalid": "Fichier de licence invalide ou expiré.", + "installFailed": "Impossible d'installer la licence." + }, + "ingestLimit": "Volume d'ingestion", + "notMetered": "Non mesuré", + "gbPerMonth": "{{gb}} Go/mois" + }, + "audit": { + "title": "Journal d'audit", + "subtitle": "Enregistrement de chaque action pertinente pour la sécurité.", + "totalEntries": "{{total}} entrées au total.", + "loadError": "Impossible de charger le journal d'audit", + "stats": { + "totalEntries": "Total des entrées", + "acrossAllTime": "Sur toute la période", + "successRate": "Taux de réussite", + "failuresOnPage_one": "{{count}} échec sur cette page", + "failuresOnPage_other": "{{count}} échecs sur cette page", + "topAction": "Action principale", + "onPage": "{{count}} sur cette page", + "uniqueActors": "Acteurs uniques", + "includingSystem": "Y compris le système" + }, + "filters": { + "title": "Filtres", + "clear": "Effacer", + "last24h": "Dernières 24h", + "failuresOnly": "Échecs uniquement", + "authEvents": "Événements d'authentification", + "actionPrefix": "Préfixe d'action", + "actionPlaceholder": "ex. auth., user.update", + "status": "Statut", + "any": "Tous", + "resourceType": "Type de ressource", + "resourceTypePlaceholder": "user, alert…", + "resourceId": "ID de ressource", + "user": "Utilisateur", + "userPlaceholder": "login…" + }, + "statusValue": { + "success": "Réussite", + "failure": "Échec" + }, + "table": { + "timestamp": "Horodatage", + "actor": "Acteur", + "action": "Action", + "resource": "Ressource", + "status": "Statut", + "ip": "IP", + "loading": "Chargement…", + "emptyTitle": "Aucune entrée ne correspond à ces filtres.", + "emptyHint": "Essayez d'effacer les filtres ou d'élargir la plage de dates.", + "system": "système", + "view": "Voir" + }, + "drawer": { + "entry": "entrée #{{id}}", + "overview": "Aperçu", + "raw": "JSON brut", + "error": "Erreur", + "actor": "Acteur", + "resource": "Ressource", + "ip": "IP", + "userAgent": "Agent utilisateur", + "session": "Session", + "metadata": "Métadonnées", + "copy": "Copier", + "copied": "Copié", + "copyJson": "Copier le JSON" + } }, - "actions": { - "cancel": "Annuler" + "team": { + "title": "Équipe", + "subtitle": "Gérez les utilisateurs et leurs rôles.", + "tabs": { + "members": "Membres", + "roles": "Rôles et permissions" + }, + "toast": { + "rolesLoadFailed": "Impossible de charger les rôles", + "userLoadFailed": "Impossible de charger l'utilisateur", + "rolesUpdated": "Rôles mis à jour", + "userReactivated": "Utilisateur réactivé", + "userDeactivated": "Utilisateur désactivé", + "tfaReset": "Authentification à deux facteurs réinitialisée", + "invitationSent": "Invitation envoyée", + "loginOrEmailInUse": "Cet identifiant ou cet e-mail est déjà utilisé", + "invalidRequest": "Requête invalide", + "noPermission": "Vous n'avez pas la permission de faire cela", + "userNotFound": "Utilisateur introuvable", + "operationFailed": "L'opération a échoué", + "emailInUse": "Cet e-mail est déjà utilisé", + "roleCreated": "Rôle créé", + "roleUpdated": "Rôle mis à jour", + "roleDeleted": "Rôle supprimé", + "roleNameInUse": "Un rôle avec cet identifiant existe déjà", + "roleImmutable": "Les rôles système ne peuvent pas être modifiés", + "permissionsLoadFailed": "Impossible de charger les permissions", + "localUserCreated": "Utilisateur local créé" + }, + "members": { + "searchPlaceholder": "Rechercher par nom ou e-mail…", + "invite": "Inviter un utilisateur", + "colUser": "Utilisateur", + "colRoles": "Rôles", + "col2fa": "2FA", + "colStatus": "Statut", + "loading": "Chargement des utilisateurs…", + "loadFailed": "Impossible de charger les utilisateurs.", + "retry": "Réessayer", + "noSearchMatch": "Aucun utilisateur ne correspond à votre recherche.", + "none": "Aucun utilisateur pour le moment.", + "noRole": "aucun", + "on": "Oui", + "off": "Non", + "countLabel_one": "{{count}} utilisateur · page {{page}} sur {{pages}}", + "countLabel_other": "{{count}} utilisateurs · page {{page}} sur {{pages}}", + "federated": "SSO" + }, + "status": { + "inactive": "Inactif", + "pendingPassword": "Mot de passe en attente", + "active": "Actif", + "pending": "Invitation en attente", + "suspended": "Suspendu" + }, + "drawer": { + "createdBy": "créé par {{actor}}", + "loading": "Chargement…", + "profileTitle": "Profil", + "profileSubtitle": "Seul l'utilisateur peut modifier ces informations, depuis son propre profil.", + "name": "Nom", + "username": "Identifiant", + "email": "E-mail", + "language": "Langue", + "accountTitle": "Compte", + "status": "Statut", + "statusActive": "Actif", + "statusInactive": "Inactif", + "tfa": "2FA", + "tfaEnabled": "Activée", + "tfaNotConfigured": "Non configuré", + "resetTfa": "Réinitialiser", + "resetTfaHint": "Désactive la 2FA de cet utilisateur pour qu'il la reconfigure à la prochaine connexion", + "resetTfaConfirmTitle": "Réinitialiser l'authentification à deux facteurs ?", + "resetTfaConfirmBody": "Cela désactive la 2FA de {{name}}. Il se connectera uniquement avec son mot de passe et pourra la reconfigurer depuis son profil.", + "resetTfaConfirm": "Réinitialiser la 2FA", + "pendingPasswordNote": "Utilise encore le mot de passe temporaire (invitation non terminée).", + "lastModified": "Modifié {{time}}", + "rolesTitle": "Rôles", + "rolesSubtitle": "Les rôles accordent des permissions de module. Un utilisateur peut en avoir plusieurs.", + "noRoleWarning": "Aucun rôle attribué — l'utilisateur n'aura accès à aucun module.", + "deactivate": "Désactiver", + "reactivate": "Réactiver", + "waitingInvite": "En attente de l'acceptation de l'invitation par l'utilisateur.", + "cancel": "Annuler", + "saving": "Enregistrement…", + "saveRoles": "Enregistrer les rôles", + "created": "créé {{time}}", + "pendingNote": "L'invitation n'a pas encore été acceptée.", + "federatedNote": "Se connecte via un fournisseur d'identité." + }, + "invite": { + "title": "Inviter un utilisateur", + "description": "Le compte est créé inactif. La personne reçoit un e-mail pour définir son mot de passe et l'activer.", + "username": "Identifiant", + "usernameHint": "Au moins 3 caractères.", + "email": "E-mail", + "firstName": "Prénom", + "lastName": "Nom", + "roles": "Rôles", + "cancel": "Annuler", + "sending": "Envoi…", + "send": "Envoyer l'invitation", + "name": "Nom", + "emailHint": "C'est l'adresse utilisée pour se connecter.", + "localDescription": "Le compte est créé avec un mot de passe et activé immédiatement. Aucun e-mail n'est envoyé.", + "modeInvite": "Inviter un utilisateur", + "modeLocal": "Créer un utilisateur local", + "passwordLabel": "Mot de passe", + "passwordPlaceholder": "Définir un mot de passe robuste", + "localUserNote": "Cet utilisateur ne recevra pas d'e-mail et sera activé automatiquement.", + "createLocal": "Créer l'utilisateur", + "passwordRules": { + "length": "Au moins 8 caractères", + "case": "Au moins une majuscule et une minuscule", + "special": "Au moins un caractère spécial" + }, + "emailInvalid": "Veuillez saisir une adresse e-mail valide" + }, + "rolePicker": { + "none": "Aucun rôle disponible." + }, + "roles": { + "loading": "Chargement des rôles…", + "loadFailed": "Impossible de charger les permissions des rôles.", + "readonlyNote": "Les rôles et leurs permissions sont définis par le système et en lecture seule. Attribuez-les aux utilisateurs depuis l'onglet Membres.", + "permissionsCount_one": "{{count}} permission", + "permissionsCount_other": "{{count}} permissions", + "modulesCount_one": "{{count}} module", + "modulesCount_other": "{{count}} modules", + "matrixTitle": "Matrice des permissions", + "matrixSubtitle": "Ce que chaque rôle peut faire, par module.", + "permission": "Permission", + "systemNote": "Les rôles système sont fournis avec la plateforme et ne sont pas modifiables. Ceux que vous créez appartiennent à ce locataire.", + "newRole": "Nouveau rôle", + "edit": "Modifier", + "delete": "Supprimer", + "systemBadge": "Système", + "createTitle": "Nouveau rôle", + "editTitle": "Modifier le rôle", + "editorSubtitle": "Choisissez ce que ce rôle peut faire. Une personne peut en cumuler plusieurs.", + "nameLabel": "Identifiant", + "nameHint": "Utilisé dans le code et l'API. Par exemple ROLE_AUDITOR.", + "displayNameLabel": "Nom affiché", + "descriptionLabel": "Description", + "permissionsLabel": "Permissions", + "selectedCount": "{{count}} sélectionnées", + "toggleAll": "toutes", + "loadingPermissions": "Chargement des permissions…", + "save": "Enregistrer le rôle", + "deleteConfirmTitle": "Supprimer ce rôle ?", + "deleteConfirmBody": "{{name}} sera supprimé. Les personnes qui n'ont que ce rôle perdront l'accès aux modules." + }, + "langDefault": "Par défaut du système", + "relative": { + "justNow": "à l'instant", + "minutesAgo": "il y a {{count}} min", + "hoursAgo": "il y a {{count}} h", + "daysAgo": "il y a {{count}} j" + }, + "roleNames": { + "ROLE_ADMIN": "Administrateur", + "ROLE_USER": "Utilisateur" + }, + "roleDescriptions": { + "ROLE_ADMIN": "Accès complet à toutes les ressources", + "ROLE_USER": "Utilisateur standard avec accès en lecture au niveau des modules" + }, + "actions": { + "read": "Lecture", + "write": "Écriture", + "delete": "Suppression" + }, + "resources": { + "adaudit": "Audit AD", + "alerts": "Alertes", + "audit": "Journal d'audit", + "compliance": "Conformité", + "config": "Configuration", + "dashboards": "Tableaux de bord", + "datasources": "Datasources", + "eventprocessing": "Traitement des événements", + "idp": "Fournisseurs d'identité", + "incidents": "Incidents", + "integrations": "Intégrations", + "loganalyzer": "Analyseur de logs", + "opensearch": "OpenSearch", + "roles": "Rôles", + "soar": "SOAR", + "users": "Utilisateurs", + "notifications": "Notifications", + "socai": "SOC AI", + "tenant": "Locataires", + "threatintel": "Renseignement sur les menaces" + } }, - "toast": { - "profileUpdated": "Profil mis à jour", - "emailInUse": "Cet e-mail est déjà utilisé", - "profileUpdateFailed": "Impossible de mettre à jour le profil", - "passwordsNoMatch": "Les mots de passe ne correspondent pas", - "passwordTooShort": "Le mot de passe doit comporter au moins 8 caractères", - "passwordChanged": "Mot de passe modifié — les autres sessions ont été déconnectées", - "currentPasswordWrong": "Le mot de passe actuel est incorrect", - "passwordChangeFailed": "Impossible de modifier le mot de passe", - "avatarTypeNotAllowed": "Type d'image non autorisé (utilisez PNG, JPEG, WEBP ou GIF)", - "avatarTooLarge": "L'image est trop volumineuse (max 2 Mo)", - "avatarUpdated": "Avatar mis à jour", - "avatarUploadFailed": "Impossible d'envoyer l'avatar", - "avatarRemoved": "Avatar supprimé", - "avatarRemoveFailed": "Impossible de supprimer l'avatar", - "sessionsLoadFailed": "Impossible de charger les sessions", - "sessionRevoked": "Session révoquée", - "sessionRevokeFailed": "Impossible de révoquer la session", - "othersSignedOut": "Autres sessions déconnectées", - "othersRevokeFailed": "Impossible de révoquer les sessions", - "tfaEmailCodeSent": "Nous avons envoyé un code à 6 chiffres à votre e-mail", - "tfaNewCodeSent": "Un nouveau code a été envoyé", - "tfaWaitResend": "Veuillez patienter avant de demander un nouveau code", - "tfaResendFailed": "Impossible de renvoyer le code", - "tfaEnterCode": "Saisissez le code à 6 chiffres", - "tfaEnabled": "Authentification à deux facteurs activée", - "tfaEnterPassword": "Saisissez votre mot de passe actuel", - "tfaDisabled": "Authentification à deux facteurs désactivée", - "tfaDisableFailed": "Impossible de désactiver le 2FA", - "tfaInvalidCode": "Code invalide ou expiré", - "tfaAlreadyEnabled": "Le 2FA est déjà activé", - "tfaTooManyRequests": "Trop de requêtes ; réessayez bientôt", - "tfaVerifyFailed": "Impossible de vérifier le code", - "genericError": "Une erreur s'est produite", - "tfaMailUnavailable": "Le second facteur par e-mail nécessite un serveur de messagerie. Configurez-le dans Paramètres → Configuration de l'e-mail." - } - }, - "home": { - "hero": { - "title": "Que souhaitez-vous savoir à partir de vos données de sécurité ?", - "placeholder": "Renseignez-vous sur Scattered Spider, cela nous concerne-t-il ?, avons-nous déjà été touchés ?, créez une règle de détection et maintenez-la à jour.", - "send": "Envoyer", - "suggestions": { - "threatHunt": "Chasse aux menaces", - "observableTriage": "Triage des observables", - "writeRule": "Écrire une règle", - "systemStatus": "État actuel du système" - } + "apiKeys": { + "title": "Clés API", + "subtitle": "Jetons d’accès programmatique pour l’API UTMStack.", + "new": "Nouvelle clé API", + "searchPlaceholder": "Rechercher par nom ou IP autorisée…", + "refresh": "Actualiser", + "loading": "Chargement des clés API…", + "loadFailed": "Impossible de charger les clés API.", + "retry": "Réessayer", + "noSearchMatch": "Aucune clé API ne correspond à votre recherche.", + "empty": "Aucune clé API pour l’instant. Créez-en une pour commencer.", + "anyIp": "Toute IP", + "never": "Jamais", + "count_one": "{{count}} clé · page {{page}} sur {{pages}}", + "count_other": "{{count}} clés · page {{page}} sur {{pages}}", + "enterprise": { + "title": "Les clés API sont une fonctionnalité Enterprise", + "body": "Émettez, restreignez et faites tourner des clés API pour l’accès programmatique à l’API UTMStack. Cette fonctionnalité est disponible dans l’édition Enterprise.", + "upgrade": "Passer à Enterprise", + "manageLicense": "Gérer votre licence" + }, + "col": { + "name": "Nom", + "allowedIps": "IP autorisées", + "created": "Créée", + "lastRotated": "Dernière rotation", + "expires": "Expire", + "status": "Statut", + "actions": "Actions" + }, + "status": { + "active": "Active", + "expiring": "Bientôt expirée", + "expired": "Expirée" + }, + "action": { + "rotate": "Faire tourner", + "edit": "Modifier", + "delete": "Supprimer" + }, + "dialog": { + "editTitle": "Modifier la clé API", + "newTitle": "Nouvelle clé API", + "name": "Nom", + "namePlaceholder": "ci-pipeline", + "allowedIps": "IP autorisées", + "allowedIpsHint": "Séparées par des virgules. Laissez vide pour autoriser toute IP.", + "expires": "Expire", + "expiresHint": "Laissez vide pour une clé qui n’expire jamais.", + "secretNote": "Le jeton secret est affiché une seule fois, juste après la création. Copiez-le alors — il ne peut pas être récupéré ensuite (seulement renouvelé).", + "cancel": "Annuler", + "saving": "Enregistrement…", + "saveChanges": "Enregistrer les modifications", + "createKey": "Créer la clé" + }, + "confirm": { + "deleteTitle": "Supprimer la clé API", + "rotateTitle": "Faire tourner la clé API", + "deleteBody": "Supprimer {{name}} ? Tout client qui l’utilise perdra immédiatement l’accès. Cette action est irréversible.", + "rotateBody": "Faire tourner {{name}} ? Un nouveau secret est émis et l’actuel cesse de fonctionner immédiatement. Le nouveau jeton est affiché une seule fois.", + "cancel": "Annuler", + "working": "En cours…", + "delete": "Supprimer", + "rotate": "Faire tourner" + }, + "reveal": { + "title": "Clé API créée", + "note": "Copiez ce secret maintenant — pour {{name}}. Il ne sera plus affiché. Si vous le perdez, faites tourner la clé.", + "copied": "Copié", + "copy": "Copier", + "done": "Terminé" + }, + "toast": { + "updated": "Clé API mise à jour", + "secretIssueFailed": "Clé créée, mais le secret n’a pas pu être émis. Utilisez Faire tourner pour en obtenir un.", + "deleted": "Clé API supprimée" + }, + "error": { + "nameTaken": "Une clé API portant ce nom existe déjà", + "enterpriseRequired": "Les clés API nécessitent l’édition Enterprise", + "notFound": "Clé API introuvable", + "invalidRequest": "Requête invalide", + "failed": "Échec de l’opération" + } }, - "kpis": { - "alerts24h": "Alertes (24 h)", - "openIncidents": "Incidents ouverts", - "openIncidentsSub": "actuellement ouverts", - "highSeverity24h": "Gravité élevée (24 h)", - "highSeveritySub": "sur {{n}} alertes", - "activePlaybooks": "Playbooks actifs", - "activePlaybooksSub": "activés" + "idp": { + "title": "Fournisseurs d'identité", + "subtitle": "Authentification unique SAML 2.0 pour votre organisation.", + "add": "Ajouter un fournisseur", + "enterprise": { + "title": "Le SSO est une fonctionnalité Enterprise", + "body": "Connectez un fournisseur d'identité SAML 2.0 (Entra ID, Okta, Google Workspace…) pour que votre équipe se connecte avec votre IdP. L'authentification unique est disponible dans l'édition Enterprise.", + "upgrade": "Passer à Enterprise" + }, + "loading": "Chargement des fournisseurs d'identité…", + "loadFailed": "Impossible de charger les fournisseurs d'identité.", + "retry": "Réessayer", + "empty": { + "title": "Aucun fournisseur d'identité configuré", + "body": "Ajoutez un fournisseur SAML 2.0 pour que votre équipe se connecte avec votre IdP d'entreprise." + }, + "card": { + "enable": "Activer", + "disable": "Désactiver", + "active": "Actif", + "disabled": "Désactivé", + "metadataUrl": "URL des métadonnées", + "spEntityId": "SP Entity ID", + "spAcsUrl": "SP ACS URL", + "loginUrl": "URL de connexion", + "copy": "Copier", + "edit": "Modifier", + "delete": "Supprimer", + "jit": "Provisioning", + "jitOn": "creates accounts on first sign-in", + "sync": "Roles", + "syncOn": "re-applied on every sign-in" + }, + "form": { + "addTitle": "Ajouter un fournisseur d'identité", + "editTitle": "Modifier le fournisseur d'identité", + "name": "Nom", + "nameHint": "Unique. Utilisé dans l'URL SSO.", + "providerType": "Type de fournisseur", + "providerTypeHint": "Une étiquette, p. ex. azure, okta, google.", + "metadataUrl": "URL des métadonnées de l'IdP", + "spEntityId": "SP Entity ID", + "spAcsUrl": "SP ACS URL", + "certificate": "Certificat SP (PEM)", + "privateKey": "Clé privée SP (PEM)", + "privateKeyHintEdit": "Laissez vide pour conserver la clé enregistrée.", + "privateKeyHintCreate": "Requise. Stockée chiffrée ; jamais affichée à nouveau.", + "privateKeyUnchanged": "•••••••• (inchangée)", + "active": "Actif (afficher sur la page de connexion)", + "cancel": "Annuler", + "saving": "Enregistrement…", + "save": "Enregistrer les modifications", + "create": "Créer le fournisseur", + "issuer": "Issuer URL", + "issuerHint": "Discovery runs against this; the provider must serve /.well-known/openid-configuration under it.", + "clientId": "Client ID", + "redirectUrl": "Redirect URL", + "redirectUrlHint": "Register this exact URL with the provider.", + "host": "Host", + "port": "Port", + "startTls": "TLS", + "startTlsOn": "Use StartTLS", + "bindDn": "Bind DN", + "bindDnHint": "A service account that may search the directory.", + "baseDn": "Base DN", + "userFilter": "User filter", + "userFilterHint": "Must contain %s, where the address typed at login is placed.", + "emailAttribute": "Email attribute", + "nameAttribute": "Name attribute", + "groupAttribute": "Group attribute", + "provisioning": "Accounts and roles", + "provisioningHint": "What happens when someone the directory vouches for signs in.", + "jit": "Create the account on first sign-in", + "defaultRole": "Default role", + "defaultRoleHint": "Given when no group matches. Without one, an unmatched sign-in is refused.", + "noDefaultRole": "None", + "groupsAttribute": "Groups attribute", + "groupsAttributeHint": "Where the provider puts group membership.", + "syncRoles": "Re-apply roles on every sign-in", + "syncRolesHint": "Roles not in the mapping are removed, so a change in the directory reaches here. Without this, a demotion never arrives.", + "mappings": "Group to role", + "mappingsHint": "A directory group on the left, the role it grants on the right.", + "addMapping": "Add", + "noMappings": "No mappings. Everyone gets the default role.", + "groupPlaceholder": "SOC Analysts", + "pickRole": "Pick a role", + "secret.saml": "SP private key", + "secret.oidc": "Client secret", + "secret.ldap": "Bind password", + "secretHintCreate": "Stored encrypted and never shown again.", + "secretHintEdit": "Leave blank to keep the stored one.", + "secretUnchanged": "inchangé", + "errors": { + "required": "Ce champ est obligatoire.", + "url": "Doit être une URL http(s) valide.", + "httpsUrl": "Doit être une URL https valide.", + "hostname": "Saisissez un hôte ou une IP sans schéma (ex. ldap.exemple.fr).", + "port": "Le port doit être un nombre entier entre 0 et 65535.", + "pemCertificate": "Ne ressemble pas à un certificat PEM (-----BEGIN/END CERTIFICATE----- manquant).", + "pemKey": "Ne ressemble pas à une clé privée PEM (-----BEGIN/END PRIVATE KEY----- manquant).", + "userFilterPlaceholder": "Le filtre doit contenir %s, là où est placée l'adresse de connexion.", + "userFilterUnbalanced": "Parenthèses déséquilibrées — la recherche ne renverra rien.", + "nameFormat": "Utilisez lettres, chiffres, points, tirets ou tirets bas (64 max). Il apparaît dans l'URL SSO, sans espaces.", + "redirectUrl": "Doit être une URL https valide, ou une URL http de loopback (localhost / 127.0.0.1 / [::1]).", + "entityId": "Doit être une URI valide, ex. https://utmstack.example.com/sp." + } + }, + "delete": { + "title": "Supprimer le fournisseur d'identité", + "body": "Supprimer {{name}} ? Les utilisateurs ne pourront plus se connecter via celui-ci. Cette action est irréversible.", + "cancel": "Annuler", + "deleting": "Suppression…", + "confirm": "Supprimer" + }, + "toast": { + "enabled": "Fournisseur activé", + "disabled": "Fournisseur désactivé", + "created": "Fournisseur d'identité créé", + "updated": "Fournisseur d'identité mis à jour", + "deleted": "Fournisseur d'identité supprimé", + "paidPlan": "Le SSO SAML nécessite un forfait payant", + "enterpriseRequired": "Le SSO nécessite l'édition Enterprise", + "notFound": "Fournisseur d'identité introuvable", + "invalid": "Configuration invalide", + "failed": "L'opération a échoué" + }, + "providerType": { + "saml": "SAML 2.0", + "oidc": "OpenID Connect", + "ldap": "LDAP / Active Directory", + "comingSoon": "pas encore disponible" + } }, - "datasources": { - "title": "Sources de données", - "viewAll": "Tout voir", - "ofTotal": "sur {{n}}", - "datasources": "sources de données", - "sendingData": "envoient des données", - "totalEvents": "Total des événements", - "noData": "Aucune donnée d'ingestion sur cette période" + "userAuditor": { + "title": "Auditeur d’utilisateurs", + "subtitle": "Comptes Active Directory observés dans vos journaux de sécurité Windows — découverts à partir d’événements de création, de connexion et de suppression.", + "export": "Exporter", + "accountsChip": "{{count}} comptes", + "overview": { + "title": "Inventaire des comptes", + "active": "actifs", + "disabled": "désactivés", + "deleted": "supprimés", + "seen24h": "{{count}} vus au cours des dernières 24 heures", + "byDomain": "Par domaine", + "grouped": "{{count}} groupés", + "unassigned": "{{count}} non assignés" + }, + "views": { + "all": "Tous les comptes", + "windows": "Windows", + "linux": "Linux", + "active": "Actifs", + "disabled": "Désactivés", + "deleted": "Supprimés", + "service": "Comptes de service", + "stale": "Inactifs (30j+)", + "o365": "O365", + "azure": "Azure", + "gcp": "GCP", + "aws": "AWS" + }, + "searchPlaceholder": "Rechercher par nom de compte ou SID…", + "allTenants": "Tous les locataires", + "filters": { + "add": "Ajouter un filtre", + "clearAll": "Tout effacer", + "filterValues": "Filtrer les valeurs…", + "loadingValues": "Chargement des valeurs…", + "noValues": "Aucune valeur trouvée.", + "pickValue": "Choisissez une valeur pour ajouter le filtre.", + "empty": "(vide)", + "cancel": "Annuler", + "addBtn": "Ajouter" + }, + "filterFields": { + "status": "Statut du cycle de vie" + }, + "ops": { + "is": "est" + }, + "refresh": "Actualiser", + "layout": { + "list": "Liste", + "cards": "Cartes" + }, + "list": { + "account": "Compte", + "identity": "Identité", + "sid": "SID", + "status": "Statut", + "lastLogon": "Dernière connexion", + "lastSeen": "Vu pour la dernière fois", + "tenant": "Locataire", + "accountId": "ID du compte", + "identityGroup": "Groupe d’identité" + }, + "status": { + "active": "Actif", + "disabled": "Désactivé", + "deleted": "Supprimé" + }, + "badge": { + "service": "service", + "stale": "inactif" + }, + "empty": "Aucun compte ne correspond à cette vue.", + "loadError": "Impossible de charger les comptes AD.", + "retry": "Réessayer", + "card": { + "lastLogon": "Dernière connexion" + }, + "pageInfo": "{{from}}–{{to}} sur {{count}}", + "drawer": { + "tenantInline": "locataire {{id}}", + "serviceAccount": "compte de service", + "stale": "inactif 30j+", + "viewInLogs": "Voir les événements dans le Log Explorer", + "copySid": "Copier le SID", + "copyUid": "Copier l’identité", + "copied": "Copié", + "identity": "Identité", + "accountName": "Nom du compte", + "domain": "Domaine", + "hostname": "Nom d’hôte", + "sid": "SID", + "uidNumber": "UID", + "machineId": "ID de machine", + "tenant": "Locataire", + "adStatus": "Statut AD", + "enabled": "Activé", + "disabled": "Désactivé", + "lifecycle": "Cycle de vie", + "created": "Compte créé", + "lastLogon": "Dernière connexion", + "lastSeen": "Vu pour la dernière fois dans les journaux", + "deleted": "Compte supprimé", + "noLifecycle": "Aucun événement de cycle de vie enregistré.", + "aliasGroup": "Groupe d’identité", + "alias": { + "add": "Ajouter un groupe d’identité", + "search": "Rechercher des groupes…", + "none": "Aucun groupe pour l’instant", + "new": "Nouveau groupe", + "unassign": "Retirer du groupe", + "unassigned": "Aucun groupe", + "newPlaceholder": "Nom du nouveau groupe (2–64 caractères)", + "createAndAssign": "Créer et assigner", + "nameTooShort": "Le nom doit compter de 2 à 64 caractères", + "updated": "Groupe d’identité mis à jour", + "updateFailed": "Impossible de mettre à jour le groupe d’identité" + } + }, + "relative": { + "justNow": "à l’instant", + "minutesAgo": "il y a {{count}}m", + "hoursAgo": "il y a {{count}}h", + "daysAgo": "il y a {{count}}j" + }, + "none": "—", + "allIdentities": "Tous les groupes d’identité", + "noneIdentity": "Aucun groupe d’identité" + }, + "connectionKey": { + "title": "Clé de connexion", + "subtitle1": "La clé que les agents présentent lors de leur enregistrement sur cette instance.", + "subtitleEmphasis": "Elle sert uniquement à l'installation des agents", + "subtitle2": "— pas pour les collecteurs, les intégrations ou l'API. Elle est gérée par l'agent-manager.", + "status": { + "label": "Statut", + "loading": "Chargement…", + "unavailable": "Agent-manager indisponible", + "active": "Active", + "unavailableHint": "Impossible de contacter l'agent-manager pour lire la clé.", + "activeHint": "Les agents peuvent s'enregistrer avec cette clé." + }, + "token": { + "title": "Clé de connexion", + "subtitle": "Traitez cette valeur comme un identifiant. La faire tourner émet une nouvelle clé pour les futures installations d'agents — les agents déjà enregistrés continuent de fonctionner.", + "loadFailedTitle": "Impossible de charger la clé de connexion", + "unavailableTitle": "Clé de connexion indisponible", + "loadFailedHint": "La clé est gérée par l'agent-manager, qui n'a pas répondu. Réessayez dans un instant.", + "retry": "Réessayer", + "show": "Afficher la clé", + "hide": "Masquer la clé", + "copy": "Copier", + "copied": "Copié", + "regenerate": "Régénérer la clé de connexion", + "confirmTitle": "Régénérer la clé ?", + "confirmBody": "Les nouvelles installations d'agents auront besoin de la nouvelle clé. Les agents déjà enregistrés continuent de fonctionner. Action irréversible.", + "regenerating": "Régénération…", + "confirmYes": "Oui, régénérer", + "cancel": "Annuler" + }, + "security": { + "title": "Recommandations de sécurité", + "subtitle": "Bonnes pratiques pour protéger cet identifiant.", + "rotateTitle": "Renouveler tous les 90 jours", + "rotateBody": "Planifiez une rotation récurrente. UTMStack peut vous envoyer un rappel par e-mail lorsque la clé a plus de 90 jours.", + "rotateAction": "Configurer un rappel", + "secretTitle": "Stockez-la comme un secret", + "secretBody": "Ne la committez pas dans le contrôle de version. Utilisez votre gestionnaire de secrets (Vault, AWS SM, etc.) et injectez-la au moment de l'installation.", + "auditTitle": "Auditez qui l'a récupérée", + "auditBody": "Chaque récupération et rotation est enregistrée dans le journal d'audit de l'application.", + "auditAction": "Voir le journal d'audit" + }, + "toast": { + "loadFailed": "Impossible de charger la clé de connexion", + "rotated": "Clé de connexion renouvelée", + "rotateFailed": "Impossible de renouveler la clé de connexion", + "copyFailed": "Impossible de copier" + } }, - "span": { - "recent": "période récente", - "days_one": "{{count}} dernier jour", - "days_other": "{{count}} derniers jours", - "hours": "dernières {{n}} h" + "dataRetention": { + "title": "Rétention des données", + "subtitle": "How long each dataset is kept, and when its records stop costing local disk.", + "loading": "Chargement…", + "loadFailed": "Could not read the store.", + "retry": "Réessayer", + "datasets": { + "logs": "Logs", + "alerts": "Alerts", + "statistics": "Ingestion statistics" + }, + "holding": "{{documents}} records · {{size}}", + "since": "since {{date}}", + "diskUsed": "Disk {{pct}}% used", + "keep": "Delete after", + "keepHint": "A record is deleted this many days after it happened, wherever it is stored by then.", + "cold": "Move to cold storage after", + "coldHint": "Older records move to object storage and stay queryable. 0 keeps everything on local disk.", + "coldUnavailable": "Set up cold storage below to move older records off local disk.", + "coldBeforeDelete": "Records have to move before they are deleted: use fewer days than the lifetime, or 0.", + "tieredNote": "This dataset moves records to cold storage. Going back to local-only needs the table rebuilt, so it cannot be turned off here.", + "days": "jours", + "save": "Enregistrer", + "saving": "Enregistrement…", + "toast": { + "saved": "Retention saved", + "noPermission": "You do not have permission to change retention", + "saveFailed": "Could not save the retention" + }, + "coldStorage": { + "title": "Cold storage", + "hint": "An object store the event store treats as a second, slower disk. Older records move there and are still queried from the same place — it is not an archive and nothing has to be restored.", + "active": "In use", + "inactive": "Not set up", + "writtenNotReady": "The bucket is configured but the store has not picked it up. Check that the deployment shares the store's configuration directory.", + "endpoint": "Bucket URL", + "accessKey": "Access key", + "secretKey": "Secret key", + "bucketLocked": "The credentials can be changed at any time. The bucket cannot, once records live in it: the parts already moved carry it.", + "enable": "Enable cold storage", + "update": "Update credentials", + "toast": { + "saved": "Cold storage configured", + "failed": "Could not configure cold storage" + }, + "kind": "Type", + "kind_s3": "Stockage objet compatible S3", + "kind_local": "Dossier local ou NFS", + "kind_azure": "Azure Blob Storage", + "accountUrl": "URL du compte de stockage", + "container": "Conteneur", + "accountName": "Nom du compte", + "accountKey": "Clé du compte", + "useRole": "Utiliser le rôle IAM du serveur au lieu de clés", + "s3Hint": "Fonctionne avec AWS S3 et tout stockage compatible S3 : MinIO, Ceph, Wasabi, Cloudflare R2 ou Google Cloud Storage (endpoint https://storage.googleapis.com// avec clés HMAC).", + "localHint": "Les enregistrements passent dans le dossier monté sur /mnt/utmstack-cold dans le magasin d'événements : un répertoire ordinaire du dossier de données, ou un partage NFS monté sur l'hôte sur /clickhouse/cold avant le démarrage du stack. Aucun identifiant requis.", + "changeWarning": "Records already moved to the current destination are not migrated. They stay there and stop being readable from here until the old destination is copied across by hand." + }, + "forbidden": { + "title": "Cette page appartient à la plateforme", + "body": "La rétention s'applique aux tables partagées par tous les locataires : seul un administrateur de la plateforme peut la lire ou la modifier." + } }, - "mitre": { - "title": "Principales techniques MITRE ATT&CK", - "explore": "Explorer", - "empty": "Aucune alerte avec technique attribuée pour le moment" + "languageSettings": { + "title": "Langue de la plateforme", + "subtitle": "Langue d'interface par défaut pour les écrans de pré-connexion, les e-mails système et les nouveaux utilisateurs. Chaque utilisateur peut choisir la sienne dans son profil.", + "label": "Langue par défaut", + "hint": "Utilisée lorsqu'un utilisateur n'a pas choisi sa propre langue.", + "save": "Enregistrer", + "saving": "Enregistrement…", + "saved": "Langue de la plateforme mise à jour", + "loadError": "Impossible de charger le paramètre de langue", + "saveError": "Impossible d'enregistrer le paramètre de langue" + }, + "branding": { + "title": "Marque", + "subtitle": "Personnalisez UTMStack avec l’identité de votre organisation — appliquée partout : écran de connexion, barre latérale, e-mails et rapports.", + "enterpriseRequired": "Le white-label est une fonctionnalité Enterprise.", + "manageLicense": "Gérer la licence", + "enable": { + "title": "White-label", + "description": "Remplacez la marque UTMStack par la vôtre sur toute la plateforme.", + "label": "Activer le white-label" + }, + "identity": { + "title": "Identité", + "productName": "Nom du produit", + "productNameHint": "Affiché dans la barre de titre, la barre latérale et les e-mails.", + "accent": "Couleur d’accent", + "accentHint": "Couleur principale des boutons, liens et états actifs.", + "custom": "Couleur personnalisée" + }, + "logos": { + "title": "Logos", + "hint": "PNG, SVG, WEBP, JPG ou ICO. Jusqu’à 5 Mo.", + "logo": "Logo (clair)", + "logoDark": "Logo (sombre)", + "favicon": "Favicon" + }, + "reports": { + "title": "Ressources de rapport", + "hint": "Intégrées dans les rapports PDF générés.", + "reportLogo": "Logo du rapport", + "reportCover": "Couverture du rapport" + }, + "asset": { + "upload": "Téléverser", + "replace": "Remplacer" + }, + "save": "Enregistrer les modifications", + "saving": "Enregistrement…", + "saved": "Marque mise à jour", + "saveError": "Impossible d’enregistrer la marque", + "uploaded": "Image téléversée", + "uploadError": "Impossible de téléverser l’image", + "loadError": "Impossible de charger la marque", + "enterprise": { + "title": "La marque blanche est une fonctionnalité Enterprise", + "body": "Remplacez le nom du produit, le logo et la couverture des rapports par les vôtres, afin que la console et tout ce qu'elle génère portent votre marque plutôt que celle d'UTMStack.", + "upgrade": "Passer à Enterprise" + }, + "restore": "Rétablir les valeurs UTMStack", + "restored": "Marque rétablie aux valeurs UTMStack" + }, + "emailConfig": { + "title": "Configuration e-mail", + "subtitle": "Serveur SMTP utilisé pour envoyer les notifications d’alertes, les rapports et les e-mails de compte.", + "server": { + "title": "Serveur SMTP", + "host": "Hôte", + "hostHint": "Nom d’hôte de votre serveur SMTP.", + "port": "Port", + "encryption": "Chiffrement", + "username": "Nom d’utilisateur", + "password": "Mot de passe", + "passwordSetHint": "Un mot de passe est enregistré. Laissez vide pour le conserver, ou saisissez-en un nouveau pour le modifier." + }, + "encryptionOpt": { + "TLS": "TLS", + "SSL": "SSL", + "NONE": "Aucun" + }, + "sender": { + "title": "Expéditeur", + "from": "Adresse d’expéditeur", + "fromHint": "Adresse depuis laquelle les e-mails sont envoyés.", + "organization": "Nom de l’organisation", + "organizationHint": "Affiché dans les e-mails de notification d’alertes et d’incidents.", + "baseUrl": "URL de base", + "baseUrlHint": "URL publique de cette instance, utilisée pour les liens dans les e-mails." + }, + "test": { + "button": "Envoyer un test", + "sending": "Envoi…", + "sentTo": "Un e-mail de test sera envoyé à {{email}}.", + "success": "E-mail de test envoyé à {{email}}", + "fail": "Impossible d’envoyer l’e-mail de test", + "fromRequired": "Définissez une adresse d’expéditeur avant de tester" + }, + "save": "Enregistrer les modifications", + "saving": "Enregistrement…", + "saved": "Configuration e-mail enregistrée", + "saveError": "Impossible d’enregistrer la configuration", + "loadError": "Impossible de charger la configuration", + "recipients": { + "alertsTitle": "Destinataires des alertes", + "incidentsTitle": "Destinataires des incidents", + "to": "À", + "cc": "Cc", + "alertsHelper": "Adresses prévenues lors de nouvelles alertes. Laissez vide et les alertes ne sont pas envoyées par e-mail.", + "incidentsHelper": "Adresses prévenues à la création d'un incident. Laissez vide et les incidents ne sont pas envoyés par e-mail.", + "add": "Ajouter" + } }, - "assets": { - "title": "Actifs les plus ciblés", - "viewAll": "Tout voir", - "asset": "Actif", - "alerts": "Alertes", - "empty": "Aucun actif ciblé dans les alertes récentes" + "dateFormat": { + "title": "Date et heure", + "subtitle": "Comment les horodatages sont affichés sur la plateforme. Les journaux sont toujours stockés en UTC.", + "timezone": { + "title": "Fuseau horaire", + "hint": "Les horodatages sont affichés dans ce fuseau horaire. Les données stockées restent en UTC.", + "system": "Par défaut du navigateur", + "now": "Maintenant : {{value}}" + }, + "format": { + "title": "Format de date", + "hint": "Style utilisé pour les dates et heures." + }, + "styles": { + "short": "Court", + "medium": "Moyen", + "long": "Long", + "full": "Complet" + }, + "save": "Enregistrer les modifications", + "saving": "Enregistrement…", + "saved": "Paramètres de date enregistrés", + "saveError": "Impossible d’enregistrer les paramètres", + "loadError": "Impossible de charger les paramètres" + }, + "about": { + "title": "À propos de cette instance", + "subtitle": "Version, licence et état du système de ce déploiement UTMStack.", + "loading": "Chargement des informations de l'instance…", + "edition": { + "enterprise": "Enterprise", + "community": "Community" + }, + "fields": { + "hostname": "Serveur", + "instanceId": "ID d'instance", + "noInstanceMeta": "Aucune métadonnée d'instance disponible." + }, + "license": { + "title": "Licence", + "enterpriseMssp": "Enterprise · MSSP", + "datasources": "Datasources", + "communityLimited": "Limite Community", + "unlimited": "Illimité", + "expires": "Expire", + "managedNote": "L'édition, les limites de datasources et l'upload de licence sont gérés sur la page Licence.", + "view": "Voir la licence", + "ingest": "Volume d'ingestion", + "notMetered": "Non mesuré", + "gbPerMonth": "{{gb}} Go/mois" + }, + "services": { + "backend": { + "name": "Backend API", + "desc": "Passerelle REST, authentification et orchestration des modules." + }, + "opensearch": { + "name": "OpenSearch", + "desc": "Stockage des logs et événements.", + "detail": "{{nodes}} nœuds · {{shards}} shards" + }, + "unreachable": "Inaccessible" + }, + "status": { + "up": "Sain", + "degraded": "Dégradé", + "down": "Hors service", + "unknown": "Inconnu" + }, + "health": { + "title": "État du système", + "allHealthy": "Tous les services sont sains. Actualisez pour revérifier.", + "issues_one": "{{count}} service nécessite une attention.", + "issues_other": "{{count}} services nécessitent une attention.", + "refresh": "Actualiser" + }, + "usage": { + "title": "Sources de données", + "subtitle": "Sources de données configurées dans ce déploiement.", + "ofUnlimited": "sur illimité", + "ofLimit": "sur {{limit}}", + "overLimit": "Au-delà de la limite sous licence — les données au-delà du plafond sont à risque.", + "configured": "configurées" + }, + "support": { + "title": "Support", + "docs": "Documentation", + "repo": "Dépôt GitHub", + "issues": "Signaler un problème", + "website": "utmstack.com" + }, + "legal": { + "title": "Mentions légales", + "license": "Licence", + "security": "Divulgation de sécurité", + "copyright": "© {{year}} UTMStack. Tous droits réservés." + } }, - "compliance": { - "title": "Score de conformité", - "reports": "Rapports", - "empty": "Aucun rapport de conformité généré pour le moment" + "logExplorer": { + "title": "Explorateur de logs", + "eventsIn": "événements dans", + "searching": "Recherche…", + "query": { + "allDataTypes": "Tous les types de données", + "dataTypes": "Types de données", + "exportCsv": "Exporter CSV", + "filterDataTypes": "Filtrer les types de données…", + "noDataTypes": "Aucun type de données", + "noDataTypesMatch": "Aucun type de données correspondant", + "noTextSearch": "Cette source n’a pas de champ plein texte — filtrez par champ", + "refresh": "Actualiser", + "run": "Exécuter", + "search": "Rechercher", + "searchPlaceholder": "Rechercher dans tous les champs…" + }, + "time": { + "15m": "15 dernières minutes", + "1h": "Dernière heure", + "6h": "6 dernières heures", + "24h": "24 dernières heures", + "7d": "7 derniers jours", + "30d": "30 derniers jours" + }, + "ops": { + "is": "est", + "isNot": "n'est pas", + "contains": "contient", + "exists": "existe", + "between": "entre", + "search": "recherche", + "isOneOf": "est parmi", + "isNotOneOf": "n'est aucun de", + "doesNotContain": "no contiene", + "startsWith": "empieza con", + "doesNotStartWith": "no empieza con", + "endsWith": "termina con", + "doesNotEndWith": "no termina con", + "doesNotExist": "no existe", + "notBetween": "no está entre", + "greaterThan": "es mayor que", + "greaterThanOrEquals": "es mayor o igual que", + "lessThan": "es menor que", + "lessThanOrEquals": "es menor o igual que" + }, + "filters": { + "label": "Filtres", + "clearAll": "Tout effacer" + }, + "fields": { + "title": "Champs", + "filterPlaceholder": "Filtrer les champs…", + "none": "Aucun champ", + "selected": "Champs sélectionnés", + "available": "Champs disponibles", + "topValues_one": "Top {{count}} valeur", + "topValues_other": "Top {{count}} valeurs", + "loading": "Chargement…", + "noValues": "Aucune valeur", + "addColumn": "Ajouter comme colonne", + "removeColumn": "Retirer la colonne du tableau", + "filterFor": "Filtrer sur la valeur", + "filterOut": "Exclure la valeur", + "empty": "(vide)" + }, + "results": { + "dataTypesFailed": "Impossible de charger les types de données.", + "endOfResults": "{{count}} événements chargés", + "loadingMore": "Chargement…", + "message": "Message", + "none": "Aucun log ne correspond à cette requête.", + "removeColumn": "Retirer {{field}}", + "retry": "Réessayer", + "searchFailed": "La recherche a échoué.", + "searching": "Recherche…", + "source": "Source", + "time": "Heure", + "scope": "Recherché dans {{dataset}} · {{dataType}}.", + "searchAllDataTypes": "Chercher dans tous les types" + }, + "detail": { + "fieldsCount_one": "{{count}} champ", + "fieldsCount_other": "{{count}} champs", + "copyJson": "Copier le JSON", + "copied": "Document copié", + "parsedFields": "Champs analysés", + "json": "JSON", + "filterFor": "Filtrer sur", + "filterOut": "Exclure", + "surrounding": "Événements environnants", + "surroundingHint": "Afficher les événements ±15 min autour de celui-ci, provenant de la même source" + }, + "view": { + "table": "Tableau", + "chart": "Graphique" + }, + "chart": { + "aggregateOn": "Agréger sur", + "per": "par", + "topValues": "— top 20 valeurs", + "building": "Construction du graphique…", + "failed": "Impossible de construire le graphique pour ce champ.", + "noData": "Aucune donnée à afficher." + }, + "intervals": { + "minute": "Minute", + "hour": "Heure", + "day": "Jour", + "week": "Semaine", + "month": "Mois", + "quarter": "Trimestre", + "year": "Année" + }, + "toast": { + "exportFailed": "L'export a échoué" + }, + "builder": { + "add": "Ajouter un filtre", + "filterValues": "Filtrer les valeurs…", + "loadingValues": "Chargement des valeurs…", + "noValues": "Aucune valeur.", + "cancel": "Annuler", + "confirm": "Ajouter", + "pickValue": "Pick a value to add the filter." + }, + "related": { + "nLogs_one": "{{count}} journal", + "nLogs_other": "{{count}} journaux", + "truncated": "Affichage des {{count}} premiers journaux liés (ensemble complet plus grand)." + }, + "saved": { + "title": "Enregistrées", + "empty": "Aucune recherche enregistrée", + "saveCurrent": "Enregistrer la recherche actuelle", + "save": "Enregistrer", + "namePlaceholder": "Nom de la recherche", + "delete": "Supprimer", + "saved": "« {{name}} » enregistrée", + "loading": "Chargement…", + "loadFailed": "Impossible de charger les recherches enregistrées", + "saveFailed": "Impossible d'enregistrer la recherche", + "deleteFailed": "Impossible de supprimer la recherche", + "unreadable": "Cette recherche enregistrée est illisible" + } }, - "health": { - "title": "État du système", - "details": "Détails", - "services": { - "backend": "API backend", - "opensearch": "Cluster OpenSearch", - "socai": "Moteur SOC-AI" - }, - "detail": { - "noClusterInfo": "aucune information sur le cluster", - "disabled": "désactivé", - "tools": "{{n}} outils", - "unreachable": "injoignable", - "pending": "…" - } - } - }, - "nav": { - "home": "Accueil", - "dashboards": "Tableaux de bord", - "dashboardList": "Liste des tableaux", - "visualizationList": "Widgets", - "newDashboard": "Nouveau tableau", - "newVisualization": "Nouveau widget", - "threatManagement": "Gestion des menaces", - "alerts": "Alertes", - "incidents": "Incidents", - "adversaryView": "Vue des adversaires", - "soar": "SOAR", - "flows": "Flux", - "executionHistory": "Historique d'exécutions", - "interactiveConsole": "Console interactive", - "logExplorer": "Explorateur de logs", - "userAuditor": "Auditeur d'utilisateurs", - "threatIntelligence": "Renseignement sur les menaces", - "threat-intel": { - "indicators": "Indicateurs", - "analyzt": "Analyste IA", - "triage": "Triage", - "report": "Rapport" + "integrations": { + "title": "Intégrations", + "searchPlaceholder": "Rechercher des intégrations…", + "noMatch": "Aucune intégration ne correspond.", + "browseMarketplace": "Parcourir la marketplace", + "loading": "Chargement des intégrations…", + "addCustom": { + "title": "Ajouter une intégration personnalisée", + "description": "Créer une nouvelle source personnalisée", + "cta": "Créer" + }, + "tabs": { + "all": "Toutes", + "agents": "Agents", + "collectors": "Collecteurs", + "cloud": "Cloud", + "custom": "Personnalisée" + }, + "kind": { + "agents & syslog": "Agent", + "device": "Collecteur", + "antivirus": "Collecteur", + "other": "Collecteur", + "custom": "Personnalisée", + "cloud": "Cloud", + "utmstack modules": "Collecteur" + }, + "status": { + "configured": "Configurée", + "available": "Disponible" + }, + "card": { + "manage": "Gérer →", + "setup": "Configurer →", + "eventsPerSec": "{{rate}} é/s", + "enabled": "Activé", + "setupShort": "Configurer" + }, + "drawer": { + "manage": "Gérer", + "openDashboard": "Ouvrir le tableau de bord", + "viewEvents": "Voir les événements", + "documentation": "Documentation", + "getInstallCmd": "Obtenir la commande d'installation", + "setupCollector": "Configurer le collecteur", + "connect": "Connecter", + "configureCustom": "Configurer la source personnalisée", + "eventsRate": "{{rate}} événements/s · {{count}} en 24h", + "manageRules": "Règles", + "manageFilters": "Filtres" + }, + "setup": { + "agent": { + "howItWorksTitle": "Comment ça marche", + "howItWorksBody": "L'agent {{name}} est un petit démon qui s'exécute sur l'hôte et transfère les événements locaux à UTMStack via une connexion TLS authentifiée. Il se met à jour automatiquement et signale son état.", + "installTitle": "Installer sur {{name}}", + "installHint": "Exécutez cette commande sur chaque hôte {{name}} que vous souhaitez surveiller. Le jeton code déjà votre espace de travail actuel.", + "afterTitle": "Ce que vous verrez après l'installation", + "after1": "L'hôte apparaît sous Sources de données dans environ 60 secondes après le démarrage de l'agent.", + "after2": "La télémétrie commence à circuler vers Log Explorer, limitée à votre espace de travail.", + "after3": "L'agent auto-signale l'état de CPU / mémoire / disque à UTMStack.", + "actionLabel": "Action", + "platformLabel": "Plateforme", + "optionsLabel": "Options", + "skipCertValidation": "Ignorer la validation du certificat TLS (serveur autosigné)", + "noRemoteControl": "Désactiver l'exécution de commandes à distance sur cet hôte", + "loadingToken": "Chargement du jeton…", + "actions": { + "install": "Installer", + "uninstall": "Désinstaller" + }, + "prereqTitle": "Prérequis d'installation", + "prereqBody": "L'agent UTMStack communique avec le serveur via les ports suivants. Assurez-vous qu'ils sont ouverts entre l'hôte et UTMStack avant l'installation :", + "sensitiveWarning": "La commande ci-dessous contient un jeton d'enrôlement sensible — ne le partagez pas.", + "uninstall": { + "title": "Désinstaller l'agent", + "body": "Exécutez cette commande sur l'hôte pour arrêter et supprimer l'agent UTMStack et ses services. Elle utilise la plateforme sélectionnée ci-dessus." + }, + "macCompat": "Requiert macOS 11 (Big Sur) ou version ultérieure sur Apple Silicon (M1/M2/M3 ou plus récent). Les Mac Intel ne sont pas pris en charge." + }, + "collector": { + "howItWorksTitle": "Comment ça marche", + "howItWorksBody": "{{name}} n'exécute pas d'agent UTMStack. À la place, vous installez le collecteur UTMStack quelque part sur le réseau que votre appareil {{name}} et UTMStack peuvent atteindre. {{name}} envoie syslog au collecteur, le collecteur analyse, normalise et transfère les événements à UTMStack.", + "step1Title": "1 · Installer le collecteur UTMStack", + "step1Hint": "Exécutez sur un hôte Linux avec accès réseau depuis l'appareil {{name}}.", + "step2Title": "2 · Configurer {{name}} pour envoyer syslog", + "step2Hint": "Sur l'appareil {{name}}, pointez la transmission syslog vers l'adresse du collecteur sur {{port}}.", + "vendorDocs": "Voir les instructions spécifiques au fournisseur", + "step3Title": "3 · Vérifier", + "step3Body": "En quelques minutes, vous devriez voir les événements de {{name}} sous source : {{source}} dans Log Explorer, et une nouvelle entrée dans Sources de données.", + "endpoint": { + "title": "Détails de connexion", + "hint": "Configurez {{name}} pour transmettre ses journaux au Collector en utilisant l'hôte et le port ci-dessous." + }, + "syslog": { + "sections": { + "sendLogs": { + "title": "1 · Envoyer les journaux à UTMStack", + "body": "Configurez votre équipement pour envoyer des messages syslog via UDP (514) ou TCP (514) à l'agent UTMStack." + }, + "enableCollector": { + "title": "2 · Activer le collecteur syslog", + "body": "Activez le collecteur de journaux et l'intégration syslog dans le fichier de configuration où votre agent UTMStack est installé." + }, + "activate": { + "title": "3 · Activer", + "body": "Activez le module UTMStack pour que les événements commencent à affluer dans Log Explorer." + } + } + }, + "netflow": { + "source": "Équipement réseau", + "step1": { + "title": "Activer l'écouteur NetFlow sur le Collector", + "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir le collecteur NetFlow sur le port 2055 :", + "note": "NetFlow utilise uniquement UDP — TCP et TLS ne sont pas pris en charge pour ce protocole." + }, + "step2": { + "title": "Configurer votre équipement pour exporter NetFlow", + "body": "Dirigez l'export NetFlow de votre routeur ou pare-feu vers l'hôte Collector sur le port {{port}} UDP. L'exemple ci-dessous concerne Cisco IOS — consultez la documentation de votre fournisseur pour les autres plateformes :", + "note": "Remplacez par le nom de l'interface où le trafic doit être surveillé (ex. GigabitEthernet0/0). Appliquez en entrée/sortie sur chaque interface concernée." + } + }, + "cisco": { + "source": "Cisco ASA", + "step1": { + "title": "Activer l'écouteur Cisco ASA sur le Collector", + "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir l'écouteur de journaux Cisco ASA :", + "note": "Pour utiliser TCP à la place de UDP, remplacez udp par tcp dans la commande ci-dessus." + }, + "step2": { + "title": "Configurer Cisco ASA pour transmettre les journaux", + "body": "Sur votre Cisco ASA, activez syslog et pointez-le vers l'hôte Collector sur le port {{port}}. Exécutez ces commandes en mode EXEC privilégié (remplacez par le nom de votre interface interne ou de gestion) :" + } + }, + "ciscoSwitch": { + "source": "Cisco Switch", + "step1": { + "title": "Activer l'écouteur Cisco Switch sur le Collector", + "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir l'écouteur de journaux Cisco Switch :", + "note": "Pour utiliser TCP à la place de UDP, remplacez udp par tcp dans la commande ci-dessus." + }, + "step2": { + "title": "Configurer le commutateur pour transmettre les journaux", + "body": "En mode EXEC privilégié sur votre commutateur Cisco, activez syslog et pointez-le vers l'hôte Collector sur le port {{port}} :" + } + }, + "ciscoMeraki": { + "source": "Cisco Meraki", + "step1": { + "title": "Activer l'écouteur Cisco Meraki sur le Collector", + "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir l'écouteur de journaux Cisco Meraki :", + "note": "Pour utiliser TCP à la place de UDP, remplacez udp par tcp dans la commande ci-dessus." + }, + "step2": { + "title": "Configurer Meraki pour transmettre les journaux", + "body": "Dans le tableau de bord Meraki, accédez à Network-wide → Configure → General, faites défiler jusqu'à la section Reporting et ajoutez un serveur syslog avec l'IP du Collector et le port {{port}}. Sélectionnez tous les rôles que vous souhaitez transmettre." + } + }, + "ciscoFirepower": { + "source": "Cisco Firepower", + "step1": { + "title": "Activer l'écouteur Cisco Firepower sur le Collector", + "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir l'écouteur de journaux Cisco Firepower :", + "note": "Pour utiliser TCP à la place de UDP, remplacez udp par tcp dans la commande ci-dessus." + }, + "step2": { + "title": "Configurer Firepower pour transmettre les journaux", + "body": "Dans Firepower Management Center (FMC), accédez à Devices → Platform Settings, modifiez ou créez une politique et naviguez vers Syslog → Syslog Servers. Ajoutez l'IP du Collector avec le port {{port}} (UDP), puis assignez la politique à vos équipements et déployez." + } + }, + "vmware": { + "source": "VMware ESXi", + "step1": { + "title": "Activer l'écouteur VMware sur le Collector", + "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir l'écouteur syslog VMware ESXi. ESXi transmet via TCP :", + "note": "Pour un canal chiffré, utilisez tls à la place de tcp (chargez d'abord les certificats sur le Collector)." + }, + "step2": { + "title": "Pointer le syslog ESXi vers le Collector", + "body": "Ouvrez une session SSH/ESXi Shell sur l'hôte (ou utilisez le vSphere Client : Host → Configure → Advanced System Settings → Syslog.global.logHost). Définissez l'hôte de journalisation distant sur {{host}}:{{port}} et rechargez la configuration :", + "note": "Sur vSphere, vous pouvez alternativement définir Syslog.global.logHost sur la même valeur tcp://host:port plutôt qu'exécuter esxcli." + }, + "step3": { + "title": "Ouvrir le pare-feu ESXi pour syslog", + "body": "Autorisez le syslog sortant à travers le pare-feu ESXi afin que l'hôte puisse atteindre le Collector :" + } + }, + "as400": { + "intro": { + "title": "Fonctionnement", + "body": "Le Collecteur AS/400 est un service Linux qui se connecte directement à vos systèmes AS/400 (IBM i) et récupère les entrées du journal de sécurité, puis les transmet de manière sécurisée à UTMStack pour la corrélation et les alertes.", + "note": "Rien n'est installé sur l'AS/400 lui-même — le Collecteur s'exécute sur un hôte Linux qui dispose d'un accès réseau à vos systèmes AS/400.", + "diagram": { + "source": "vos journaux", + "edge1": "journaux", + "collector": "Collecteur AS/400", + "collectorSub": "extrait depuis AS/400", + "edge2": "sécurisé", + "utmstackSub": "alertes & corrélation" + } + }, + "install": { + "title": "Installer le Collecteur AS/400", + "body": "Exécutez cette commande sur un hôte Linux pouvant atteindre à la fois UTMStack et vos systèmes AS/400 via le réseau.", + "reuse": "Le Collecteur AS/400 est déjà installé ? Ignorez cette étape — ajoutez simplement vos serveurs au fichier de configuration à l'étape suivante." + }, + "configure": { + "title": "Ajouter vos serveurs AS/400", + "body": "Modifiez as400-config.yaml dans le répertoire d'installation du collecteur et ajoutez chaque système AS/400 que vous souhaitez surveiller :", + "note": "Vous pouvez répertorier plusieurs serveurs. Le collecteur surveille ce fichier et recharge automatiquement à l'enregistrement — aucun redémarrage nécessaire." + }, + "journal": { + "title": "Activer la journalisation d'audit sur AS/400", + "body": "Sur chaque système AS/400, assurez-vous que le journal d'audit de sécurité QAUDJRN est actif. Consultez la documentation IBM pour les étapes précises — la procédure varie selon les versions d'IBM i." + }, + "uninstall": { + "title": "Optionnel — Désinstaller le Collecteur", + "body": "Exécutez cette commande sur l'hôte où le Collecteur AS/400 est installé pour arrêter le service et supprimer tous les fichiers." + } + }, + "bitdefender": { + "intro": { + "title": "Fonctionnement", + "body": "UTMStack se connecte à Bitdefender GravityZone à l'aide de votre clé API pour configurer l'Event Push Service. GravityZone envoie ensuite les événements de sécurité directement à UTMStack pour la corrélation et les alertes.", + "diagram": { + "source": "événements d'endpoint", + "edge": "Event Push Service", + "utmstackSub": "alertes & corrélation" + }, + "note": "Aucun agent n'est installé sur GravityZone — UTMStack s'enregistre lui-même comme destination d'envoi à l'aide d'identifiants API en lecture seule." + }, + "whitelist": { + "title": "Autoriser les IP Bitdefender", + "body": "Les adresses IP Bitdefender GravityZone suivantes doivent être autorisées à travers votre pare-feu sur le port 8000 afin que l'Event Push Service puisse atteindre UTMStack :", + "note": "Ajoutez ces IP à votre pare-feu ou groupe de sécurité avant de finaliser la configuration." + }, + "apiSection": "Obtenir les identifiants API", + "api": { + "myAccount": { + "title": "Ouvrir Mon compte", + "body": "Dans la console Bitdefender GravityZone, cliquez sur Mon compte." + }, + "accessUrl": { + "title": "Noter l'URL d'accès", + "body": "Faites défiler jusqu'à la section Control Center API et enregistrez l'URL d'accès — vous la saisirez dans le formulaire d'identifiants ci-dessous. Ouvrez ensuite la section des clés API et cliquez sur Ajouter en haut du tableau." + }, + "createKey": { + "title": "Créer une clé API", + "body": "Rédigez une description pour la clé API, sélectionnez l'option Event Push Service API et cliquez sur Enregistrer. Copiez la clé générée." + } + }, + "companySection": "Obtenir les ID d'entreprise", + "company": { + "myCompany": { + "title": "Ouvrir Ma société", + "body": "Dans la console GravityZone, cliquez sur Ma société." + }, + "licensing": { + "title": "Noter les ID d'entreprise", + "body": "Ouvrez la section Licences et enregistrez les ID d'entreprise que vous souhaitez surveiller — saisissez-les séparés par des virgules dans le formulaire d'identifiants ci-dessous." + } + }, + "credentials": { + "title": "Saisir les identifiants", + "body": "Renseignez l'URL d'accès, la clé API, l'IP publique UTMStack (vers laquelle GravityZone enverra les événements) et les identifiants d'entreprise à surveiller. UTMStack vérifie les identifiants avant l'enregistrement." + }, + "fields": { + "accessUrl": { + "label": "URL d'accès GravityZone" + }, + "connectionKey": { + "label": "Clé API" + }, + "utmPublicIP": { + "label": "IP publique UTMStack" + }, + "companyIds": { + "label": "Identifiants d'entreprise (séparés par des virgules)" + } + } + }, + "eset": { + "source": "ESET Protect", + "step1": { + "title": "Activer l'écouteur ESET sur le Collector", + "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir l'écouteur syslog ESET :", + "note": "Pour utiliser TCP à la place de UDP, remplacez udp par tcp dans la commande ci-dessus." + }, + "console": { + "moreMenu": { + "title": "Ouvrir le menu Plus", + "body": "Dans la barre latérale de la console ESET Protect, cliquez sur le menu Plus." + }, + "serverConfig": { + "title": "Ouvrir les paramètres du serveur", + "body": "Sous Plus, ouvrez la section Paramètres du serveur (Configuration du serveur)." + }, + "advanced": { + "title": "Développer les paramètres avancés", + "body": "Cliquez sur Paramètres avancés pour afficher la liste complète des options de configuration." + }, + "syslog": { + "title": "Configurer le serveur Syslog", + "body": "Faites défiler jusqu'à Serveur Syslog, activez Exporter les journaux vers Syslog et définissez la destination sur l'hôte Collector au port {{port}} (UDP). ESET envoie LEEF/syslog, que le Collector ingère en tant que type de données antivirus-esmc-eset." + } + } + }, + "kaspersky": { + "source": "Kaspersky Security", + "step1": { + "title": "Activer l'écouteur Kaspersky sur le Collector", + "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir l'écouteur syslog Kaspersky :", + "note": "Pour utiliser TCP à la place de UDP, remplacez udp par tcp dans la commande ci-dessus." + }, + "console": { + "consoleSettings": { + "title": "Ouvrir les paramètres de la console → Intégration", + "body": "Dans la barre latérale de Kaspersky Security Center, ouvrez Paramètres de la console et cliquez sur le sous-menu Intégration." + }, + "siem": { + "title": "Ouvrir les paramètres d'intégration SIEM", + "body": "Sous Intégration, sélectionnez SIEM et cliquez sur le lien Paramètres pour ouvrir la configuration d'export." + }, + "configure": { + "title": "Configurer l'export SIEM", + "body": "Activez l'export et configurez Kaspersky pour envoyer les événements au format Splunk (CEF) vers l'hôte Collector sur le port {{port}} (UDP). Le Collector les ingère en tant que type de données antivirus-kaspersky." + } + } + }, + "sophos": { + "intro": { + "title": "Sophos Central — Plugin API", + "body": "Sophos Central fournit des API sécurisées pour récupérer les données d'événements et d'alertes. UTMStack se connecte à ces API pour centraliser la surveillance et améliorer votre visibilité de sécurité — aucun agent ni collector requis.", + "diagram": { + "source": "Sophos Central API", + "edge": "HTTPS API", + "utmstackSub": "Ingère & corrèle" + }, + "note": "UTMStack interroge l'API Sophos Central selon un calendrier. Assurez-vous que les identifiants API que vous créez ci-dessous disposent d'un accès en lecture aux événements et aux alertes." + }, + "apiSection": "Générer des identifiants API dans Sophos Central", + "steps": { + "apiCredentials": { + "title": "Ouvrir la gestion des identifiants API", + "body": "Dans Sophos Central Admin, accédez à Paramètres généraux → Gestion des identifiants API." + }, + "addCredential": { + "title": "Créer un nouvel identifiant", + "body": "Cliquez sur Ajouter un identifiant. Indiquez un Nom et une Description, sélectionnez le Rôle approprié, puis cliquez sur Ajouter." + }, + "copyIds": { + "title": "Copier le Client ID et le Client Secret", + "body": "Copiez le Client ID et le Client Secret et conservez-les en lieu sûr.", + "secretNote": "Le Client Secret n'est affiché qu'une seule fois. Sauvegardez-le en lieu sûr avant de fermer cette boîte de dialogue." + } + }, + "credentialsSection": "Se connecter à UTMStack", + "credentials": { + "title": "Ajouter des identifiants Sophos Central", + "body": "Saisissez les identifiants que vous venez de créer. Vous pouvez ajouter plusieurs comptes Sophos en cliquant sur Ajouter un groupe de configuration." + }, + "fields": { + "clientId": { + "label": "Client ID" + }, + "apiKey": { + "label": "Client Secret / Clé API" + } + } + }, + "webroot": { + "sections": { + "login": { + "title": "1 · Se connecter à la console de gestion", + "body": "Connectez-vous à la console de gestion Webroot. Elle s'ouvre sur l'onglet Sites." + }, + "openSettings": { + "title": "2 · Ouvrir les paramètres", + "body": "Cliquez sur l'onglet Paramètres." + }, + "apiAccess": { + "title": "3 · Ouvrir l'accès API", + "body": "Depuis l'onglet Abonnements, cliquez sur l'onglet Accès API." + }, + "createCredential": { + "title": "4 · Créer un identifiant client", + "body": "Cliquez sur Nouveau et renseignez le Nom et la Description. Lisez le contrat SecureAnywhere Business Solution et Unity API, puis cliquez sur Créer." + }, + "noteClientSecret": { + "title": "5 · Copier l'identifiant client et le secret", + "body": "Sauvegardez le Client ID depuis la liste et le Client Secret qui n'est affiché qu'une seule fois. Cliquez sur \"J'ai noté le secret client\" pour confirmer." + }, + "fillForm": { + "title": "6 · Remplir le formulaire", + "body": "Fournissez le client ID et le client secret à UTMStack. Vous pouvez ajouter plusieurs groupes de configuration Webroot si nécessaire." + }, + "activate": { + "title": "7 · Activer", + "body": "Activez le module UTMStack pour que les événements Webroot commencent à affluer." + } + } + }, + "sentinelOne": { + "source": "SentinelOne", + "step1": { + "title": "Activer l'écouteur SentinelOne sur le Collector", + "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir l'écouteur syslog SentinelOne. SentinelOne diffuse CEF via TCP :", + "note": "Pour un canal chiffré, utilisez tls à la place de tcp (chargez d'abord les certificats sur le Collector)." + }, + "console": { + "settings": { + "title": "Ouvrir les paramètres de SentinelOne", + "body": "Dans la barre latérale de la console de gestion SentinelOne, cliquez sur le menu Paramètres." + }, + "syslog": { + "title": "Configurer l'intégration Syslog", + "body": "Accédez à Intégrations → Syslog et activez-le. Définissez l'hôte sur {{host}} et le port sur {{port}}, conservez le format CEF, cliquez sur Test pour vérifier la connexion, puis Enregistrer." + } + } + }, + "office365": { + "intro": { + "title": "Fonctionnement", + "body": "UTMStack se connecte à Microsoft 365 via une application Azure AD enregistrée et interroge l'API Office 365 Management Activity pour les événements d'audit et de sécurité. Aucun agent n'est installé dans votre tenant.", + "diagram": { + "source": "événements d'audit et de sécurité", + "edge": "Management API", + "utmstackSub": "corrélation & alertes" + }, + "note": "UTMStack nécessite un accès API en lecture seule — aucune permission d'écriture n'est demandée." + }, + "appSection": "Enregistrement d'application Azure", + "steps": { + "azurePortal": { + "title": "Ouvrir Microsoft Entra ID", + "body": "Ouvrez le portail Azure (portal.azure.com) et cliquez sur Microsoft Entra ID." + }, + "appRegistrations": { + "title": "Accéder aux inscriptions d'applications", + "body": "Dans le menu de gauche, cliquez sur Inscriptions d'applications." + }, + "registerApp": { + "title": "Inscrire une nouvelle application", + "body": "Cliquez sur Nouvelle inscription. Nommez-la UTMStack O365 Agent, sélectionnez Comptes dans cet annuaire organisationnel uniquement (Monolocataire), puis cliquez sur S'inscrire." + }, + "clientSecret": { + "title": "Créer un secret client", + "body": "Accédez à Certificats et secrets → Nouveau secret client. Ajoutez une description, définissez l'expiration à 730 jours (24 mois), puis cliquez sur Ajouter.", + "copyNote": "Copiez immédiatement la valeur du secret — elle n'est affichée qu'une seule fois et ne peut pas être récupérée ultérieurement." + }, + "apiPermissions": { + "title": "Ajouter des autorisations pour l'API Office 365 Management", + "body": "Accédez à Autorisations API → Ajouter une autorisation et recherchez Office 365 Management APIs." + }, + "activityFeed": { + "title": "Accorder les autorisations ActivityFeed", + "body": "Sélectionnez Autorisations d'application et ajoutez ActivityFeed.Read et ActivityFeed.ReadDlp. Cliquez sur Accorder le consentement de l'administrateur et confirmez." + }, + "graphPermissions": { + "title": "Ajouter des autorisations Microsoft Graph", + "body": "De retour dans Ajouter une autorisation, cliquez sur Microsoft Graph." + }, + "delegatedPermissions": { + "title": "Ajouter des autorisations déléguées SecurityAlert", + "body": "Sélectionnez Autorisations déléguées et ajoutez SecurityAlert.Read.All et SecurityAlert.ReadWrite.All. Cliquez sur Accorder le consentement de l'administrateur et confirmez." + }, + "appPermissions": { + "title": "Ajouter des autorisations d'application SecurityAlert", + "body": "Sélectionnez Autorisations d'application et ajoutez SecurityAlert.Read.All et SecurityAlert.ReadWrite.All. Cliquez sur Accorder le consentement de l'administrateur et confirmez." + }, + "noteIds": { + "title": "Copier les identifiants de l'application", + "body": "Accédez à la Vue d'ensemble de l'application et copiez l'ID d'application (client) et l'ID de répertoire (tenant). Vous avez également besoin de la valeur secrète copiée à l'étape 4." + } + }, + "credentialsSection": "Identifiants", + "credentials": { + "title": "Connecter votre tenant Microsoft 365", + "body": "Saisissez les informations des étapes précédentes. UTMStack vérifie les identifiants avant l'enregistrement. Vous pouvez ajouter plusieurs groupes de configuration." + }, + "fields": { + "tenantId": { + "label": "ID du tenant (ID de répertoire)" + }, + "clientId": { + "label": "Client ID (ID d'application)" + }, + "clientSecret": { + "label": "Secret client" + }, + "cloudEnv": { + "label": "Environnement cloud (facultatif)", + "hint": "Commercial (par défaut), GCC, GCCHigh ou DoD" + } + } + }, + "github": { + "source": "GitHub", + "step1": { + "title": "Activer l'écouteur de webhook GitHub sur le Collector", + "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir l'écouteur de webhook HTTPS pour GitHub :", + "tokenNote": "Le terminal affichera un jeton secret — copiez-le immédiatement. Il ne sera plus affiché." + }, + "certWarning": { + "title": "GitHub exige un certificat TLS signé par une autorité de certification", + "body": "GitHub n'envoie des webhooks qu'aux points de terminaison HTTPS disposant d'un certificat émis par une autorité de certification publique (les certificats auto-signés sont refusés). Assurez-vous que l'hôte du Collector possède un certificat de domaine valide avant d'enregistrer le webhook." + }, + "step2": { + "title": "Enregistrer le webhook dans GitHub", + "body": "Dans votre dépôt ou organisation, allez dans Settings → Webhooks → Add webhook et remplissez le formulaire :", + "payloadUrl": "URL de payload", + "contentType": "Type de contenu", + "secret": "Secret", + "secretHint": "Collez le jeton affiché par le Collector à l'étape précédente.", + "events": "Quels événements", + "eventsHint": "Tout envoyer — ou sélectionner des types d'événements spécifiques." + } + }, + "salesforce": { + "sections": { + "openSetup": { + "title": "1 · Ouvrir Setup", + "body": "Accédez à Setup et sélectionnez « Setup for the current app » en haut à droite de l'écran." + }, + "appManager": { + "title": "2 · Ouvrir App Manager", + "body": "Saisissez « App Manager » dans la zone de recherche rapide et sélectionnez App Manager." + }, + "newConnectedApp": { + "title": "3 · Créer une nouvelle Connected App", + "body": "Sur l'écran Lightning Experience App Manager, cliquez sur « New Connected App » et remplissez les champs." + }, + "oauthSettings": { + "title": "4 · Activer les paramètres OAuth", + "body": "Dans la section « API (Enable OAuth Settings) », cochez « Enable OAuth Settings » et utilisez https://login.salesforce.com/services/oauth2/success comme URL de rappel." + }, + "oauthScopes": { + "title": "5 · Ajouter des portées OAuth", + "body": "Sélectionnez « Access Connect REST API resources (chatter_api) » sous Selected OAuth Scopes." + }, + "save": { + "title": "6 · Enregistrer", + "body": "Enregistrez vos modifications et sélectionnez Continue sur l'écran suivant." + }, + "manageConsumer": { + "title": "7 · Ouvrir Manage Consumer Details", + "body": "Dans votre Connected App, allez dans « API (Enable OAuth Settings) » et cliquez sur « Manage Consumer Details » à côté de Consumer Key and Secret." + }, + "copyCredentials": { + "title": "8 · Copier la clé et le secret consommateur", + "body": "Vérifiez votre identité. La Consumer Key et le Consumer Secret apparaissent sous « Consumer Details ». Copiez les deux avec le bouton Copy." + }, + "fillForm": { + "title": "9 · Remplir le formulaire", + "body": "Fournissez la Consumer Key, le Consumer Secret, le nom d'utilisateur Salesforce et le mot de passe à UTMStack." + }, + "activate": { + "title": "10 · Activer", + "body": "Activez le module UTMStack pour que les événements Salesforce commencent à affluer." + } + } + }, + "iis": { + "sections": { + "enableModule": { + "title": "1 · Activer le module IIS Filebeat", + "body": "Sur l'hôte de l'agent UTMStack, exécutez :\ncd \"C:\\Program Files\\UTMStack\\UTMStack Agent\\beats\\filebeat\\\" && filebeat modules enable iis" + }, + "configureModule": { + "title": "2 · Configurer le module IIS", + "body": "Modifiez C:\\Program Files\\UTMStack\\UTMStack Agent\\beats\\filebeat\\modules.d\\iis.yml comme indiqué ci-dessous pour pointer vers les répertoires de journaux IIS que vous souhaitez transmettre." + }, + "activate": { + "title": "3 · Activer", + "body": "Activez le module UTMStack pour que les événements IIS commencent à affluer." + } + } + }, + "filebeat": { + "sections": { + "installRsyslog": { + "title": "1 · Installer rsyslog", + "body": "Assurez-vous que rsyslog est installé sur l'hôte. Utilisez le gestionnaire de paquets de votre distribution (apt, dnf, yum)." + }, + "configureRsyslog": { + "title": "2 · Configurer rsyslog pour transférer vers UTMStack", + "body": "Modifiez /etc/rsyslog.conf (ou un fichier sous /etc/rsyslog.d/) et ajoutez une règle de transfert ciblant l'agent UTMStack via UDP ou TCP sur le port 514." + }, + "restartRsyslog": { + "title": "3 · Redémarrer rsyslog", + "body": "Redémarrez le service rsyslog : sudo systemctl restart rsyslog" + }, + "enableCollector": { + "title": "4 · Activer le collecteur de journaux Linux", + "body": "Activez le collecteur de journaux et l'intégration Linux Logs dans le fichier de configuration où votre agent UTMStack est installé." + } + } + }, + "json": { + "sections": { + "overview": { + "title": "1 · Utiliser le point de terminaison d'ingestion HTTP/JSON", + "body": "UTMStack accepte des événements JSON arbitraires via HTTPS. Envoyez une requête POST avec une liste d'événements ; UTMStack les analyse et les achemine via votre analyseur configuré." + }, + "auth": { + "title": "2 · S'authentifier avec un jeton de fédération", + "body": "Obtenez un jeton de fédération depuis Settings → Connection Key et envoyez-le comme jeton Bearer dans l'en-tête Authorization." + } + }, + "endpoint": { + "title": "Point de terminaison d'ingestion JSON", + "hint": "Utilisez cette structure de requête depuis votre application ou une tâche cron. Le jeton est la clé de fédération issue de Settings → Connection Key." + } + }, + "ldap": { + "sections": { + "openServerManager": { + "title": "1 · Ouvrir Server Manager", + "body": "Sur le contrôleur de domaine AD, ouvrez Server Manager." + }, + "addRoles": { + "title": "2 · Ajouter des rôles et des fonctionnalités", + "body": "Choisissez « Add roles and features » dans le menu Manage." + }, + "selectCertServices": { + "title": "3 · Sélectionner Active Directory Certificate Services", + "body": "À l'étape Server Roles, sélectionnez Active Directory Certificate Services." + }, + "installServices": { + "title": "4 · Installer le service de rôle Autorité de certification", + "body": "À l'étape Role Services, sélectionnez Certificate Authority et terminez l'assistant." + }, + "configureAdCs": { + "title": "5 · Configurer AD CS", + "body": "Après l'installation, cliquez sur la notification pour configurer AD CS et choisissez Certificate Authority comme service de rôle à configurer." + }, + "pickCaType": { + "title": "6 · Choisir le type d'autorité de certification", + "body": "Choisissez Enterprise CA → Root CA → Create a new private key." + }, + "setValidity": { + "title": "7 · Définir la période de validité du certificat", + "body": "Définissez une période de validité adaptée à votre organisation (5 ans est courant)." + }, + "confirm": { + "title": "8 · Confirmer et installer", + "body": "Vérifiez les paramètres et cliquez sur Configure pour terminer." + }, + "restart": { + "title": "9 · Redémarrer le contrôleur de domaine", + "body": "Redémarrez le contrôleur de domaine pour que LDAPS devienne disponible sur TCP 636." + }, + "activate": { + "title": "10 · Activer", + "body": "Activez le module UTMStack pour que les événements d'audit AD commencent à affluer." + } + } + }, + "oracle": { + "source": "Serveur Oracle DB", + "step1": { + "title": "Activer l'intégration Oracle sur le Collector", + "body": "Sur le serveur où le Collector est installé, exécutez la commande suivante pour commencer à écouter les journaux Oracle :", + "note": "Le Collector commencera à recevoir des événements syslog d'Oracle sur le port 7021." + }, + "step2": { + "title": "Configurer rsyslog sur le serveur Oracle", + "body": "Créez le fichier de configuration rsyslog :", + "editBody": "Ouvrez le fichier avec votre éditeur préféré et ajoutez la configuration suivante. Remplacez BASEDIR par votre chemin d'installation Oracle (p. ex., /u01/app/oracle) et par l'adresse IP ou le nom d'hôte du Collector :", + "note": "Utilisez @@:7021 au lieu de @ si vous préférez une livraison TCP." + }, + "step3": { + "title": "Redémarrer rsyslog", + "body": "Appliquez la nouvelle configuration en redémarrant le service rsyslog :" + }, + "step4": { + "title": "Valider la configuration", + "body": "Envoyez des messages de journal de test pour vérifier qu'UTMStack reçoit des événements des trois sources de journaux Oracle :", + "note": "Ouvrez Log Explorer et recherchez le texte du message de test ci-dessus pour confirmer leur réception." + } + }, + "vulnerabilities": { + "sections": { + "overview": { + "title": "1 · À propos du scanner de vulnérabilités", + "body": "Le module de vulnérabilités UTMStack analyse les actifs découverts via le module Asset Management et compare leur empreinte à la base de données CVE." + }, + "scope": { + "title": "2 · Définir la portée de l'analyse", + "body": "Utilisez le module Asset Management pour enregistrer les hôtes que vous souhaitez analyser. Le scanner de vulnérabilités s'exécutera périodiquement sur ces hôtes." + }, + "activate": { + "title": "3 · Activer", + "body": "Activez le module UTMStack pour démarrer l'analyse." + } + } + }, + "assetScanner": { + "sections": { + "overview": { + "title": "1 · À propos d'Asset Management", + "body": "Le module Asset Management découvre et inventorie les hôtes, les logiciels et les services sur votre réseau." + }, + "agentRequirement": { + "title": "2 · Exigence d'agent", + "body": "La découverte des actifs utilise des agents UTMStack installés sur des hôtes Linux, Windows ou macOS. Installez l'agent sur les systèmes que vous souhaitez inventorier." + }, + "activate": { + "title": "3 · Activer", + "body": "Activez le module UTMStack pour démarrer la découverte des actifs." + } + } + }, + "fileIntegrity": { + "sections": { + "enableAuditPolicy": { + "title": "1 · Activer l'audit d'accès aux objets", + "body": "Sur l'hôte Windows, ouvrez Group Policy → Computer Configuration → Windows Settings → Security Settings → Advanced Audit Policy Configuration → Object Access et activez « Audit File System »." + }, + "configureFolderAuditing": { + "title": "2 · Configurer l'audit des dossiers", + "body": "Pour chaque dossier à surveiller, ouvrez Properties → Security → Advanced → Auditing et ajoutez une entrée d'audit pour les principaux et les types d'accès souhaités." + }, + "verifyEvents": { + "title": "3 · Vérifier l'apparition des événements dans le journal de sécurité", + "body": "Ouvrez Event Viewer et confirmez que les événements 4663/4670 sont générés lors de l'accès aux objets audités." + }, + "activate": { + "title": "4 · Activer", + "body": "Activez le module UTMStack pour que les événements d'intégrité de fichiers commencent à transiter." + } + } + }, + "socAi": { + "sections": { + "overview": { + "title": "1 · À propos de SOC AI", + "body": "SOC AI enrichit UTMStack avec un analyste basé sur LLM qui résume les alertes et suggère les prochaines étapes. Il fonctionne avec le fournisseur que vous configurez." + }, + "chooseProvider": { + "title": "2 · Choisir un fournisseur", + "body": "Sélectionnez un fournisseur — OpenAI, Anthropic, Azure OpenAI, Google Gemini, Ollama, Mistral, DeepSeek, Groq, ou un point de terminaison compatible OpenAI personnalisé." + }, + "configureCredentials": { + "title": "3 · Configurer les identifiants", + "body": "Fournissez la clé API et, le cas échéant, le nom du modèle et l'URL du point de terminaison." + }, + "activate": { + "title": "4 · Activer", + "body": "Activez le module UTMStack pour que SOC AI commence à traiter les alertes." + } + } + }, + "utmstack": { + "intro": { + "title": "Fonctionnement", + "body": "Cette intégration surveille votre déploiement UTMStack en auto-surveillance. Un collecteur léger installé sur l'hôte UTMStack suit les journaux des conteneurs Docker de la plateforme et les renvoie vers UTMStack pour corrélation et alertes.", + "diagram": { + "source": "Journaux Docker", + "sourceSub": "Conteneurs UTMStack", + "edge1": "suivi", + "collector": "Collecteur", + "collectorSub": "sur l'hôte", + "edge2": "ingestion", + "utmstackSub": "Corrèle et alerte" + } + }, + "requirements": { + "title": "Fonctionne uniquement sur l'hôte UTMStack", + "body": "Cette intégration ne peut être installée que sur une instance UTMStack fonctionnant sous Ubuntu ou une distribution de la famille Red Hat. Installez le collecteur directement sur le serveur UTMStack." + }, + "install": { + "title": "Installer le collecteur", + "body": "Sur l'hôte UTMStack, sélectionnez votre système d'exploitation et exécutez la commande ci-dessous pour télécharger et installer le collecteur d'auto-surveillance :", + "sensitiveWarning": "Cette commande contient un jeton de connexion sensible. Traitez-le comme un mot de passe et ne le partagez pas." + }, + "after": { + "title": "Ce que vous verrez après l'installation", + "item1": "Le collecteur s'enregistre et apparaît sous Sources de données.", + "item2": "Les journaux des conteneurs UTMStack commencent à transiter en moins d'une minute.", + "item3": "Les événements deviennent consultables dans Log Explorer sous le type de données utmstack." + }, + "uninstall": { + "title": "Désinstaller le collecteur", + "body": "Pour supprimer le collecteur d'auto-surveillance de l'hôte UTMStack, exécutez :" + } + }, + "windowsFaa": { + "sections": { + "enableAuditPolicy": { + "title": "1 · Activer l'audit d'accès aux objets", + "body": "Sur l'hôte Windows, ouvrez Group Policy → Computer Configuration → Windows Settings → Security Settings → Advanced Audit Policy Configuration → Object Access et activez « Audit File System »." + }, + "configureFolderAuditing": { + "title": "2 · Configurer l'audit des dossiers", + "body": "Pour chaque dossier à surveiller, ouvrez Properties → Security → Advanced → Auditing et ajoutez une entrée d'audit pour les principaux et les types d'accès souhaités." + }, + "activate": { + "title": "3 · Activer", + "body": "Activez le module UTMStack pour que les événements d'activité de fichiers commencent à transiter." + } + } + }, + "awsBeanstalk": { + "sections": { + "openConsole": { + "title": "1 · Ouvrir la console Elastic Beanstalk", + "body": "Dans la console AWS, ouvrez Elastic Beanstalk." + }, + "environment": { + "title": "2 · Ouvrir la page de gestion de l'environnement", + "body": "Accédez à la page de gestion de l'environnement que vous souhaitez surveiller." + }, + "configuration": { + "title": "3 · Ouvrir la configuration", + "body": "Sélectionnez Configuration." + }, + "software": { + "title": "4 · Modifier la configuration logicielle", + "body": "Dans la catégorie Software configuration, sélectionnez Modify." + }, + "s3LogStorage": { + "title": "5 · Activer le stockage des journaux S3", + "body": "Sous S3 log storage, sélectionnez Rotate logs pour téléverser les journaux pivotés vers Amazon S3." + }, + "cloudwatchStreaming": { + "title": "6 · Activer le streaming CloudWatch Logs", + "body": "Sous Instance log streaming to CloudWatch Logs, activez le streaming, définissez la période de rétention et choisissez si vous souhaitez téléverser les journaux existants." + }, + "activate": { + "title": "7 · Activer", + "body": "Activez le module UTMStack pour que les événements Beanstalk commencent à transiter." + } + } + }, + "awsFargate": { + "sections": { + "taskDefinition": { + "title": "1 · Mettre à jour la définition de tâche", + "body": "Dans la définition de tâche pour la tâche Fargate, définissez le logDriver sur « awslogs » et spécifiez le nom du groupe de journaux." + }, + "cloudwatchLogs": { + "title": "2 · Confirmer que CloudWatch Logs reçoit les journaux", + "body": "Ouvrez la console CloudWatch Logs et confirmez que le groupe de journaux est alimenté lors de l'exécution des tâches." + }, + "iamPrerequisite": { + "title": "3 · Prérequis utilisateur IAM", + "body": "Cette intégration partage les identifiants avec le module AWS IAM User — assurez-vous qu'il est configuré avec CloudWatchLogsReadOnlyAccess." + }, + "activate": { + "title": "4 · Activer", + "body": "Activez le module UTMStack pour que les événements Fargate commencent à transiter." + } + } + }, + "awsIamUser": { + "sections": { + "iamConsole": { + "title": "1 · Ouvrir la console IAM", + "body": "Dans la console AWS, accédez à IAM → Users → Add users." + }, + "createUser": { + "title": "2 · Créer l'utilisateur", + "body": "Choisissez un nom d'utilisateur (ex. utmstack-ingest). Sélectionnez l'accès programmatique." + }, + "programmaticAccess": { + "title": "3 · Définir le type d'identifiant", + "body": "Sélectionnez « Access key — Programmatic access »." + }, + "attachPolicy": { + "title": "4 · Attacher la politique de lecture CloudWatch", + "body": "Attachez la politique gérée par AWS CloudWatchLogsReadOnlyAccess." + }, + "review": { + "title": "5 · Vérifier l'utilisateur", + "body": "Vérifiez les détails de l'utilisateur et cliquez sur Create user." + }, + "copyKeys": { + "title": "6 · Copier l'identifiant de clé d'accès et le secret", + "body": "Copiez l'Access key ID et la Secret access key — le secret n'est affiché qu'une seule fois." + }, + "createLogGroup": { + "title": "7 · Créer un groupe de journaux CloudWatch", + "body": "Dans CloudWatch → Log groups, créez un groupe de journaux nommé « utmstack » — les autres intégrations AWS y enverront leurs données." + }, + "fillForm": { + "title": "8 · Remplir le formulaire", + "body": "Fournissez la clé d'accès, le secret, la région par défaut et le nom du groupe de journaux (ex. « utmstack ») à UTMStack." + }, + "activate": { + "title": "9 · Activer", + "body": "Activez le module UTMStack pour que les événements AWS commencent à transiter." + } + } + }, + "awsLambda": { + "sections": { + "iamPrerequisite": { + "title": "1 · Prérequis utilisateur IAM", + "body": "Lambda repose sur le module AWS IAM User — assurez-vous que cette intégration est configurée en premier avec CloudWatchLogsReadOnlyAccess." + }, + "cloudwatchStream": { + "title": "2 · Lambda diffuse déjà vers CloudWatch Logs", + "body": "AWS Lambda publie automatiquement les journaux d'exécution dans CloudWatch Logs sous /aws/lambda/. UTMStack ingère depuis le groupe de journaux configuré lors de la configuration de l'utilisateur IAM." + }, + "activate": { + "title": "3 · Activer", + "body": "Activez le module UTMStack pour que les événements Lambda commencent à transiter." + } + } + }, + "awsSqlServer": { + "sections": { + "openRds": { + "title": "1 · Ouvrir la console Amazon RDS", + "body": "Ouvrez https://console.aws.amazon.com/rds/." + }, + "pickDb": { + "title": "2 · Sélectionner l'instance de base de données", + "body": "Dans le volet de navigation, sélectionnez Databases et choisissez l'instance de base de données à surveiller." + }, + "modify": { + "title": "3 · Modifier l'instance", + "body": "Sélectionnez Modify." + }, + "logExports": { + "title": "4 · Activer les exportations de journaux", + "body": "Dans la section Log exports, sélectionnez Error log et Agent log pour publier dans CloudWatch Logs." + }, + "apply": { + "title": "5 · Appliquer les modifications", + "body": "Cliquez sur Continuer, puis sur Modifier l'instance DB sur la page de récapitulatif." + }, + "activate": { + "title": "6 · Activer", + "body": "Activez le module UTMStack pour que les événements SQL Server commencent à affluer." + } + } + }, + "awsPostgresql": { + "sections": { + "openRds": { + "title": "1 · Ouvrir la console Amazon RDS", + "body": "Ouvrez https://console.aws.amazon.com/rds/." + }, + "pickDb": { + "title": "2 · Sélectionner l'instance DB", + "body": "Dans le panneau de navigation, sélectionnez Databases et choisissez l'instance DB à modifier." + }, + "logExports": { + "title": "3 · Activer les exportations de journaux", + "body": "Dans la section Log exports, sélectionnez le journal PostgreSQL à publier dans CloudWatch Logs." + }, + "apply": { + "title": "4 · Appliquer les modifications", + "body": "Cliquez sur Continuer, puis sur Modifier l'instance DB sur la page de récapitulatif." + }, + "activate": { + "title": "5 · Activer", + "body": "Activez le module UTMStack pour que les événements PostgreSQL commencent à affluer." + } + } + }, + "awsTrafficMirror": { + "sections": { + "createTarget": { + "title": "1 · Créer une cible de mise en miroir du trafic", + "body": "Dans la console VPC, créez un Traffic Mirror Target pointant vers l'interface réseau de la VM de l'agent UTMStack." + }, + "createFilter": { + "title": "2 · Créer un filtre de mise en miroir du trafic", + "body": "Créez un Traffic Mirror Filter et ajoutez des règles entrantes/sortantes pour les protocoles à mettre en miroir (ex. tout TCP, tout UDP)." + }, + "createSession": { + "title": "3 · Créer une session de mise en miroir du trafic", + "body": "Créez une Traffic Mirror Session associant chaque interface réseau source à la cible et au filtre créés." + }, + "iamPrerequisite": { + "title": "4 · Prérequis utilisateur IAM", + "body": "Assurez-vous que le module AWS IAM User est également configuré afin que UTMStack puisse lire les journaux de flux VPC si nécessaire." + }, + "activate": { + "title": "5 · Activer", + "body": "Activez le module UTMStack pour que le trafic mis en miroir commence à être analysé." + } + } + }, + "forwarder": { + "intro": { + "title": "Fonctionnement", + "body": "Les journaux transitent de {{source}} vers le UTMStack Collector, qui les envoie de manière sécurisée dans UTMStack pour la corrélation et les alertes. Rien n'est installé sur {{source}} — seul le Collector doit être exécuté sur un hôte de votre réseau." + }, + "diagram": { + "sourceSub": "vos journaux", + "forwarder": "Collector", + "forwarderSub": "écoute sur {{port}}", + "utmstack": "UTMStack", + "utmstackSub": "alertes & corrélation", + "flow1": "journaux", + "flow2": "sécurisé" + }, + "noInstall": "Rien n'est installé sur {{source}} — vous redirigez uniquement ses journaux vers le Collector.", + "install": { + "title": "Installer le UTMStack Collector", + "body": "Le Collector est un service Linux qui reçoit les journaux de vos appareils et les envoie à UTMStack. Un seul Collector gère plusieurs intégrations simultanément.", + "reuse": "Vous avez déjà un Collector en cours d'exécution ? Ignorez cette étape — redirigez {{source}} vers celui existant en utilisant l'hôte et le port indiqués ci-dessous." + }, + "tls": { + "title": "Optionnel — Activer le chiffrement TLS", + "intro": "Par défaut, le listener accepte du TCP/UDP en clair. Pour chiffrer le trafic syslog en transit, chargez d'abord vos fichiers de certificat, puis réactivez le listener avec le protocole tls.", + "step1": "1 · Charger votre certificat et votre clé (une fois par Collector)", + "step1Note": "Un certificat CA facultatif peut être ajouté comme troisième argument. Omettez-le pour utiliser le certificat feuille comme CA.", + "step2": "2 · Réactiver le listener avec TLS" + }, + "httpsCerts": { + "title": "Chargez le certificat TLS sur le Collector", + "body": "Cette intégration utilise un listener HTTPS sur le port {{port}}, le Collector a donc besoin d'un certificat et d'une clé chargés avant de l'activer :" + }, + "uninstall": { + "title": "Optionnel — Désinstaller le Collector", + "body": "Exécutez cette commande sur l'hôte où le Collector est installé pour arrêter le service et supprimer tous ses fichiers." + }, + "instanceHeader": { + "title": "En-tête d'autorisation", + "body": "Incluez cet en-tête Authorization dans chaque requête envoyée à l'instance. Le secret de la clé API n'est révélé qu'une seule fois à sa génération — copiez-le à ce moment et collez-le à la place du placeholder ci-dessous.", + "tabSimple": "Simple", + "tabBatch": "Lot" + }, + "manualCommand": { + "title": "Optional — Enable via the command line instead", + "intro": "Prefer the terminal? SSH into the Collector host and run the command below — it matches whatever protocol and port you have selected above.", + "certStep": "1 · Load your certificate and key (once per Collector)", + "enableStep": "2 · Enable the integration" + } + }, + "aix": { + "source": "Serveur AIX", + "step1": { + "title": "Activer le listener AIX sur le Collector", + "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir le listener de journaux AIX :", + "note": "Pour utiliser TCP au lieu de UDP, remplacez udp par tcp dans la commande ci-dessus." + }, + "step2": { + "title": "Configurer AIX pour transmettre les journaux", + "body": "Sur votre système AIX, configurez le service syslog pour rediriger ses journaux vers l'hôte du Collector sur le port {{port}}. Consultez la documentation IBM pour la syntaxe exacte — elle varie selon les versions d'AIX." + } + }, + "deceptivebytes": { + "source": "Deceptive Bytes", + "step1": { + "title": "Activer le listener Deceptive Bytes sur le Collector", + "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir le listener syslog Deceptive Bytes :", + "note": "Pour utiliser TCP au lieu de UDP, remplacez udp par tcp dans la commande ci-dessus." + }, + "step2": { + "title": "Configurer Deceptive Bytes pour transmettre les journaux", + "body": "Dans la console de gestion Deceptive Bytes, configurez le transfert syslog pour envoyer les événements à l'hôte du Collector sur le port {{port}} (UDP). Deceptive Bytes émet du syslog au format CEF, que le Collector ingère sous le type de données deceptive-bytes." + } + }, + "mikrotik": { + "source": "Routeur MikroTik", + "step1": { + "title": "Activer le listener MikroTik sur le Collector", + "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir le listener syslog MikroTik :", + "note": "Pour utiliser TCP au lieu de UDP, remplacez udp par tcp dans la commande ci-dessus." + }, + "step2": { + "title": "Configurer MikroTik pour transmettre les journaux", + "body": "Sur le routeur MikroTik, créez une action de journalisation distante pointant vers l'hôte du Collector sur le port {{port}} et associez-la aux rubriques de journaux pertinentes. Exécutez la commande suivante depuis le CLI RouterOS (Terminal dans Winbox) :", + "note": "Vous pouvez également configurer cela via Winbox : System → Logging → onglet Actions (ajouter une action Remote) → puis l'onglet Rules (ajouter des règles pointant vers la nouvelle action)." + } + }, + "fortigate": { + "source": "Pare-feu FortiGate", + "step1": { + "title": "Activer le listener FortiGate sur le Collector", + "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir le listener syslog FortiGate :", + "note": "Pour utiliser TCP au lieu de UDP, remplacez udp par tcp dans la commande ci-dessus." + }, + "step2": { + "title": "Configurer FortiGate pour transmettre les journaux", + "body": "Sur le FortiGate, pointez syslog vers l'hôte du Collector sur le port {{port}}. Exécutez la commande suivante depuis le CLI FortiOS (ou utilisez Log & Report → Log Settings → Syslog dans l'interface graphique) :", + "note": "Remplacez l'adresse du serveur si le Collector s'exécute sur un hôte différent. Pour plusieurs collecteurs syslog, utilisez syslogd2/syslogd3/syslogd4." + } + }, + "fortiweb": { + "source": "FortiWeb WAF", + "step1": { + "title": "Activer le listener FortiWeb sur le Collector", + "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir le listener syslog FortiWeb :", + "note": "Pour utiliser TCP au lieu de UDP, remplacez udp par tcp dans la commande ci-dessus." + }, + "step2": { + "title": "Configurer FortiWeb pour transmettre les journaux", + "body": "Sur le FortiWeb, créez une politique syslog pointant vers l'hôte du Collector sur le port {{port}} et activez la journalisation syslog. Exécutez la commande suivante depuis le CLI FortiWeb (ou utilisez Log & Report → Log Policy → Syslog Policy dans l'interface graphique) :", + "note": "Assurez-vous que les types de journaux pertinents (Attack, Event, Traffic) sont activés pour être envoyés à syslog dans les paramètres Log & Report." + } + }, + "paloalto": { + "source": "Pare-feu Palo Alto", + "step1": { + "title": "Activer le listener Palo Alto sur le Collector", + "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir le listener syslog Palo Alto :", + "note": "Pour utiliser TCP au lieu de UDP, remplacez udp par tcp dans la commande ci-dessus." + }, + "step2": { + "title": "Créer un profil de serveur Syslog", + "body": "Dans PAN-OS, accédez à Device → Server Profiles → Syslog et ajoutez un profil. Définissez l'adresse du serveur sur {{host}}, le transport sur UDP, le port sur {{port}} et le format sur BSD." + }, + "step3": { + "title": "Transmettre les journaux et valider", + "body": "Créez un profil Log Forwarding (Objects → Log Forwarding) qui envoie les journaux Traffic, Threat et d'autres types au profil syslog ci-dessus, associez-le à vos règles de Security policy (Policies → Security → règle → Actions → Log Forwarding), puis Commit." + } + }, + "pfsense": { + "source": "Pare-feu pfSense", + "step1": { + "title": "Activer le listener pfSense sur le Collector", + "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir le listener syslog pfSense :", + "note": "Pour utiliser TCP au lieu de UDP, remplacez udp par tcp dans la commande ci-dessus." + }, + "step2": { + "title": "Activer la journalisation distante dans pfSense", + "body": "Dans l'interface web pfSense, accédez à Status → System Logs → Settings. Sous Remote Logging Options, cochez Enable Remote Logging, définissez un serveur de journaux distant sur {{host}}:{{port}}, choisissez les journaux à envoyer (ou Everything), puis cliquez sur Save." + } + }, + "sonicwall": { + "source": "Pare-feu SonicWall", + "step1": { + "title": "Activer le listener SonicWall sur le Collector", + "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir le listener syslog SonicWall :", + "note": "Pour utiliser TCP au lieu de UDP, remplacez udp par tcp dans la commande ci-dessus." + }, + "step2": { + "title": "Ajouter un serveur Syslog dans SonicOS", + "body": "Dans SonicOS, accédez à Device → Log → Syslog (Manage → Log → Syslog sur les anciens firmwares) et ajoutez un serveur Syslog avec l'adresse {{host}} et le port {{port}}. Définissez le Syslog Format sur ArcSight (CEF) — UTMStack analyse SonicWall en CEF — puis cliquez sur Apply." + } + }, + "sophosxg": { + "source": "Sophos Firewall", + "step1": { + "title": "Activer le listener Sophos Firewall sur le Collector", + "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir le listener syslog Sophos Firewall :", + "note": "Pour utiliser TCP au lieu de UDP, remplacez udp par tcp dans la commande ci-dessus." + }, + "step2": { + "title": "Ajouter un serveur Syslog dans Sophos Firewall", + "body": "Dans la console Sophos Firewall (SFOS), accédez à System → System services → Log settings et ajoutez un serveur Syslog avec l'adresse {{host}} et le port {{port}}. Choisissez les types de journaux à transmettre (firewall, IPS, ATP, web, etc.) et cliquez sur Apply." + } + }, + "suricata": { + "source": "Suricata IDS", + "step1": { + "title": "Activer l'écouteur Suricata sur le Collector", + "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir l'écouteur Suricata :", + "note": "Pour utiliser TCP à la place de UDP, remplacez udp par tcp dans la commande ci-dessus." + }, + "step2": { + "title": "Envoyer les journaux EVE de Suricata vers syslog", + "body": "Suricata est ingéré en JSON (EVE). Sur l'hôte Suricata, modifiez suricata.yaml et configurez la sortie eve-log pour écrire vers syslog :", + "note": "Puis redémarrez Suricata : sudo systemctl restart suricata" + }, + "step3": { + "title": "Transmettre syslog vers le Collector", + "body": "Dirigez la facility local5 (vers laquelle Suricata écrit désormais) vers le Collector. Ajoutez cette règle dans /etc/rsyslog.d/60-utmstack-suricata.conf sur l'hôte Suricata :", + "note": "Utilisez @@ au lieu de @ pour TCP. Puis redémarrez rsyslog : sudo systemctl restart rsyslog" + } + }, + "o365_graph": { + "intro": { + "title": "Comment ça fonctionne", + "body": "UTMStack se connecte à Microsoft 365 avec une app Azure AD enregistrée et interroge Microsoft Graph pour les événements de sécurité : alertes, incidents, audit du répertoire, sign-ins, détections de risque, requêtes de hunting et journaux d'audit Purview. Aucun agent n'est installé dans votre tenant.", + "diagram": { + "source": "événements de sécurité", + "edge": "Microsoft Graph", + "utmstackSub": "corrélation & alertes" + }, + "note": "UTMStack nécessite un accès en lecture seule à l'API Graph — aucune permission d'écriture n'est demandée." + }, + "appSection": "Enregistrement d'application Azure", + "steps": { + "azurePortal": { + "title": "Ouvrir Microsoft Entra ID", + "body": "Ouvrez le Portail Azure (portal.azure.com) et cliquez sur Microsoft Entra ID." + }, + "appRegistrations": { + "title": "Aller aux Enregistrements d'application", + "body": "Dans le menu de gauche, cliquez sur Enregistrements d'application." + }, + "registerApp": { + "title": "Enregistrer une nouvelle application", + "body": "Cliquez sur Nouvel enregistrement. Nommez-la UTMStack Graph Dev, sélectionnez Comptes de ce seul annuaire d'organisation (monolocataire) et cliquez sur Enregistrer." + }, + "clientSecret": { + "title": "Créer un secret client", + "body": "Allez dans Certificats et secrets → Nouveau secret client. Ajoutez une description, définissez l'expiration sur 730 jours (24 mois) et cliquez sur Ajouter.", + "copyNote": "Copiez la valeur du secret immédiatement — elle n'est affichée qu'une seule fois et ne pourra pas être récupérée ensuite." + }, + "apiPermissions": { + "title": "Ajouter les permissions Microsoft Graph", + "body": "Allez dans Permissions de l'API → Ajouter une permission et sélectionnez Microsoft Graph, puis choisissez Permissions d'application." + }, + "graphPermissions": { + "title": "Ajouter les quatre permissions Graph", + "body": "Ajoutez SecurityEvents.Read.All, Directory.Read.All, AuditLog.Read.All et IdentityRiskEvent.Read.All." + }, + "adminConsent": { + "title": "Accorder le consentement administrateur", + "body": "De retour dans Permissions de l'API, cliquez sur Accorder le consentement administrateur pour {tenant} et confirmez." + }, + "noteIds": { + "title": "Copier les ID de l'application", + "body": "Allez dans la Vue d'ensemble de l'application et copiez l'ID d'application (client) et l'ID d'annuaire (tenant). Vous avez également besoin de la valeur du secret copiée à l'étape 4." + } + }, + "credentialsSection": "Identifiants", + "credentials": { + "title": "Connecter votre tenant Microsoft 365", + "body": "Saisissez les informations des étapes ci-dessus. UTMStack vérifie les identifiants avant l'enregistrement. Vous pouvez ajouter plusieurs groupes de configuration." + }, + "fields": { + "tenantId": { + "label": "ID de tenant (ID d'annuaire)" + }, + "clientId": { + "label": "ID de client (ID d'application)" + }, + "clientSecret": { + "label": "Secret client" + }, + "cloudEnv": { + "label": "Environnement cloud (facultatif)", + "hint": "Commercial (par défaut), GCC, GCCHigh ou DoD" + } + } + } + }, + "cloud": { + "howItWorksTitle": "Comment ça marche", + "howItWorksBody": "{{name}} s'exécute entièrement dans UTMStack — pas d'agent ni de collecteur à déployer. Fournissez des identifiants API en lecture seule et UTMStack extraira les événements selon un horaire, les analysera et les ingérera dans Log Explorer.", + "connectionTitle": "Connexion", + "noFields": "Aucun champ de connexion configuré.", + "testConnection": "Tester la connexion", + "save": "Enregistrer", + "afterTitle": "Ce que vous verrez après la connexion", + "after1": "UTMStack effectue un remplissage initial des événements récents.", + "after2": "Ensuite, les événements sont extraits toutes les 1–5 minutes (dépend de l'API).", + "after3": "L'intégration apparaît sous Sources de données avec l'état d'extraction et le décalage actuels.", + "tenants": { + "title": "Groupes de configuration configurés", + "empty": "Aucun groupe de configuration pour le moment. Ajoutez le premier ci-dessous.", + "loading": "Chargement des groupes de configuration…", + "nameLabel": "Nom du groupe de configuration", + "namePlaceholder": "p. ex. acme-prod", + "add": "Ajouter un groupe de configuration", + "update": "Mettre à jour le groupe de configuration", + "delete": "Supprimer", + "edit": "Modifier", + "cancel": "Annuler", + "editing": "Édition : {{name}}", + "selectFile": "Sélectionner un fichier", + "replaceFile": "Remplacer le fichier", + "fileLoaded": "Fichier chargé", + "invalidJson": "Impossible de lire le fichier comme JSON.", + "createError": "Impossible de créer le groupe de configuration. Veuillez réessayer.", + "updateError": "Impossible de mettre à jour le groupe de configuration. Veuillez réessayer.", + "createSuccess": "Groupe de configuration créé avec succès.", + "updateSuccess": "Groupe de configuration mis à jour avec succès." + }, + "google": { + "sections": { + "createTopic": { + "title": "1 · Créer un sujet Pub/Sub", + "body": "Dans la console Google Cloud, ouvrez Pub/Sub → Sujets et créez un nouveau sujet. UTMStack recevra les événements via ce sujet.", + "docLabel": "Ouvrir la page des topics Pub/Sub" + }, + "createSubscription": { + "title": "2 · Créer un abonnement", + "body": "Dans le sujet, créez un abonnement de type Pull. UTMStack récupère les messages depuis cet abonnement." + }, + "configureSubscription": { + "title": "3 · Configurer l'abonnement", + "body": "Réglez la durée de conservation des messages sur une valeur correspondant à votre tolérance aux interruptions (7 jours par défaut convient). Laissez le délai d'acquittement à 10 secondes et l'expiration sur « Ne jamais expirer »." + }, + "logsRouter": { + "title": "4 · Ouvrir le routeur de logs", + "body": "Allez dans Logging → Routeur de logs et créez un nouveau sink. C'est ce qui transfère les logs de votre projet vers le sujet Pub/Sub créé ci-dessus." + }, + "sinkDestination": { + "title": "5 · Pointer le sink vers le sujet", + "body": "Choisissez Sujet Cloud Pub/Sub comme destination du sink et sélectionnez le sujet créé. Utilisez les filtres d'inclusion/exclusion pour limiter ce qui est transféré." + }, + "serviceAccount": { + "title": "6 · Créer un compte de service", + "body": "Ouvrez IAM et administration → Comptes de service et créez un nouveau compte de service. Attribuez-lui le rôle Éditeur Pub/Sub pour qu'UTMStack puisse lire l'abonnement.", + "docLabel": "Ouvrir la page des comptes de service" + }, + "serviceAccountKey": { + "title": "7 · Générer une clé pour le compte de service", + "body": "Ouvrez le compte de service, allez dans l'onglet Clés et ajoutez une nouvelle clé. Choisissez JSON comme type de clé." + }, + "downloadKey": { + "title": "8 · Télécharger et charger la clé JSON", + "body": "Enregistrez le fichier JSON téléchargé par Google : son contenu va dans le champ « Clé JSON du compte de service » ci-dessous." + } + }, + "fields": { + "projectId": { + "label": "ID de projet" + }, + "subscription": { + "label": "Nom de l'abonnement" + }, + "jsonKey": { + "label": "Clé JSON du compte de service" + } + }, + "intro": { + "title": "Fonctionnement", + "body": "UTMStack lit l'activité d'audit directement depuis Google Cloud via Pub/Sub. Un sink du Logs Router diffuse les journaux de votre projet dans un topic Pub/Sub ; UTMStack exécute un collecteur interne qui lit un abonnement Pull sur ce topic à l'aide d'une clé de compte de service. Rien n'est installé dans votre projet GCP.", + "diagram": { + "source": "Cloud Logging", + "edge1": "Logs Router", + "pubsub": "Pub/Sub", + "pubsubSub": "topic + abonnement", + "edge2": "collecte", + "utmstackSub": "alertes & corrélation" + }, + "note": "Aucun agent ne s'exécute dans GCP — UTMStack collecte les messages de l'abonnement Pub/Sub à l'aide de la clé JSON du compte de service que vous fournissez ci-dessous." + }, + "credentials": { + "title": "Configuration Pub/Sub", + "body": "Utilisez les valeurs collectées ci-dessus pour configurer UTMStack. Vous pouvez surveiller plusieurs projets en enregistrant des configurations supplémentaires.", + "mapping": { + "intro": "Référence des champs", + "projectId": "Project ID — le projet GCP qui contient votre topic, votre abonnement et votre sink", + "subscription": "Nom de l'abonnement — l'abonnement Pull créé à l'étape 2", + "jsonKey": "Clé JSON du compte de service — le fichier téléchargé à l'étape 8" + } + } + }, + "azure": { + "sections": { + "sharedAccessPolicy": { + "title": "2 · Ajouter une politique d'accès partagé", + "body": "Ouvrez l'Event Hub → Politiques d'accès partagé et créez une politique avec uniquement l'autorisation Listen." + }, + "connectionString": { + "title": "3 · Copier la chaîne de connexion principale", + "body": "Ouvrez la politique et copiez la chaîne de connexion principale. Elle ressemble à : Endpoint=sb://...;SharedAccessKeyName=...;SharedAccessKey=..." + }, + "consumerGroup": { + "title": "4 · Créer un consumer group dédié", + "body": "Ouvrez l'Event Hub → Consumer groups et créez-en un nouveau pour UTMStack. Ne réutilisez pas $Default — donnez à UTMStack son propre groupe pour éviter les conflits de checkpoints avec d'autres consommateurs.", + "warn": "Créez un groupe de consommateurs spécifiquement pour UTMStack. N'utilisez pas $Default ni aucun autre groupe déjà utilisé — réutiliser un groupe de consommateurs entre des consommateurs non liés peut entraîner des comportements inattendus et des pertes d'événements. Toutes les instances UTMStack doivent partager le même groupe de consommateurs afin de traiter les événements ensemble." + }, + "storageContainer": { + "title": "6 · Créer un conteneur dans le compte de stockage", + "body": "Dans le compte de stockage → Conteneurs, créez un nouveau conteneur. Notez le nom du conteneur et la chaîne de connexion du compte (Clés d'accès → Chaîne de connexion)." + }, + "eventGrid": { + "title": "7 · Enregistrer le fournisseur de ressources Event Grid", + "body": "Dans Abonnements → Fournisseurs de ressources, enregistrez Microsoft.EventGrid si ce n'est pas déjà fait. Cela permet à Azure de transférer les événements au niveau de l'abonnement vers votre Event Hub." + }, + "createEventHub": { + "title": "Créer un Event Hub", + "body": "Dans le portail Azure, créez un espace de noms Event Hubs et un Event Hub à l'intérieur. UTMStack lira les événements depuis ce hub.", + "docLabel": "Démarrage rapide : créer un hub d'événements via le portail Azure" + }, + "createStorageAccount": { + "title": "Créer un Storage Account", + "body": "UTMStack a besoin d'un Storage Account pour enregistrer sa position de lecture. Créez-en un dans la même région que l'Event Hub.", + "docLabel": "Démarrage rapide : créer un compte de stockage" + }, + "storageConnection": { + "title": "Copier la chaîne de connexion du Storage Account", + "body": "Récupérez la chaîne de connexion du Storage Account avec clé via : All services → Storage accounts → votre compte → Access keys. UTMStack l'utilise pour stocker les points de contrôle de l'Event Hub." + }, + "createEventSubscription": { + "title": "Créer un abonnement aux événements", + "body": "Dans le panneau Événements de l'abonnement, créez un nouvel événement en cliquant sur Events → Event Subscription." + }, + "configureEventSubscription": { + "title": "Diriger l'abonnement aux événements vers votre Event Hub", + "body": "Configurez l'abonnement aux événements pour envoyer les journaux vers l'Event Hub créé à l'étape 1." + } + }, + "fields": { + "eventHubConnection": { + "label": "Chaîne de connexion Event Hub" + }, + "consumerGroup": { + "label": "Consumer group" + }, + "storageContainer": { + "label": "Nom du conteneur de stockage" + }, + "storageConnection": { + "label": "Chaîne de connexion du compte de stockage" + } + }, + "intro": { + "title": "Fonctionnement", + "body": "UTMStack lit l'activité d'audit directement depuis un Azure Event Hub. Vous configurez votre abonnement Azure pour diffuser les événements dans un Event Hub ; UTMStack exécute un collecteur interne qui lit ce hub et enregistre sa progression dans un Storage Account. Rien n'est installé dans votre tenant Azure.", + "diagram": { + "source": "événements d'abonnement", + "edge1": "diffuse vers", + "eventHub": "Event Hub", + "eventHubSub": "flux d'événements", + "edge2": "collecte", + "utmstackSub": "alertes & corrélation" + }, + "note": "Aucun agent ne s'exécute dans Azure — UTMStack collecte les événements depuis l'Event Hub à l'aide des chaînes de connexion que vous fournissez ci-dessous." + }, + "sampleLabel": "Exemple de chaîne de connexion :", + "credentials": { + "title": "Configuration de l'Event Hub", + "body": "Utilisez les données collectées dans les étapes ci-dessus pour configurer UTMStack. Vous pouvez ajouter plusieurs Event Hubs en enregistrant des configurations supplémentaires.", + "mapping": { + "intro": "Référence des champs", + "eventHubConnection": "Chaîne de connexion Event Hub — valeur obtenue à l'étape 3", + "consumerGroup": "Groupe de consommateurs — valeur obtenue à l'étape 4", + "storageContainer": "Nom du conteneur de stockage — valeur obtenue à l'étape 6", + "storageConnection": "Chaîne de connexion du compte de stockage — valeur obtenue à l'étape 7" + } + } + }, + "aws": { + "fields": { + "accessKeyId": { + "label": "ID de clé d'accès AWS" + }, + "secretAccessKey": { + "label": "Clé d'accès secrète AWS" + }, + "region": { + "label": "Région AWS par défaut" + }, + "logGroupName": { + "label": "Nom du log group" + } + }, + "intro": { + "title": "Fonctionnement", + "body": "UTMStack lit l'activité d'audit directement depuis AWS CloudWatch Logs. CloudTrail capture les appels API et les événements de gestion sur votre compte AWS, les transmet à un groupe de journaux CloudWatch, et UTMStack interroge ce groupe pour ingérer et corréler les événements.", + "diagram": { + "source": "événements API", + "edge1": "CloudTrail", + "cloudwatchSub": "groupes de journaux", + "edge2": "interroge", + "utmstackSub": "alertes & corrélation" + }, + "note": "Aucun agent n'est installé sur AWS — UTMStack collecte les événements de journal à l'aide des informations d'identification IAM en lecture seule que vous fournissez ci-dessous." + }, + "iamSection": "Configurer l'utilisateur IAM", + "iam": { + "dashboard": { + "title": "Ouvrir le tableau de bord IAM", + "body": "Ouvrez la console AWS, accédez au tableau de bord IAM et sélectionnez Users." + }, + "addUser": { + "title": "Ajouter un utilisateur", + "body": "Cliquez sur Add user, saisissez un nom d'utilisateur descriptif et passez à l'étape suivante." + }, + "attachPolicy": { + "title": "Attacher la politique en lecture seule", + "body": "Sous Permissions, attachez la politique requise. Sélectionnez CloudWatchLogsReadOnlyAccess pour un accès CloudWatch en lecture seule." + }, + "createUser": { + "title": "Créer l'utilisateur", + "body": "Vérifiez la configuration et cliquez sur Create user pour provisionner le compte." + }, + "openUser": { + "title": "Ouvrir le nouvel utilisateur", + "body": "Ouvrez l'utilisateur nouvellement créé en cliquant sur son nom pour consulter les détails et gérer les informations d'identification." + }, + "securityTab": { + "title": "Accéder aux informations d'identification de sécurité", + "body": "Sélectionnez l'onglet Security credentials pour créer des clés d'accès programmatiques." + }, + "createKey": { + "title": "Créer une clé d'accès", + "body": "Cliquez sur Create access key et choisissez l'option pour une application s'exécutant en dehors d'AWS (accès programmatique)." + }, + "confirmKey": { + "title": "Confirmer la création", + "body": "Confirmez la création de la clé d'accès. AWS génèrera un Access Key ID et une Secret Access Key." + }, + "downloadKey": { + "title": "Enregistrer vos informations d'identification", + "body": "Téléchargez le fichier d'informations d'identification ou copiez l'Access Key ID et la Secret Access Key dans un emplacement sécurisé — la Secret Access Key n'est affichée qu'une seule fois." + } + }, + "credentials": { + "title": "Saisir les informations d'identification", + "body": "Collez l'Access Key ID et la Secret Access Key obtenus dans les étapes précédentes. UTMStack vérifie les informations d'identification auprès d'AWS avant de les enregistrer." + }, + "cloudwatchSection": "Configurer AWS CloudWatch", + "cloudwatch": { + "createGroup": { + "title": "Créer un groupe de journaux CloudWatch", + "body": "Ouvrez la console CloudWatch, choisissez Log management et cliquez sur Create log group." + }, + "nameGroup": { + "title": "Nommer le groupe de journaux et définir la rétention", + "body": "Saisissez le nom du groupe de journaux utmstack et définissez la rétention à 1 jour. Cliquez sur Create log group." + }, + "openTrail": { + "title": "Ouvrir CloudTrail et créer un journal de suivi", + "body": "Dans la console CloudTrail, cliquez sur Create trail pour commencer à configurer un nouveau journal de suivi." + }, + "configureTrail": { + "title": "Configurer la livraison, la validation et l'intégration CloudWatch", + "body": "Dans le formulaire de création CloudTrail, définissez les options suivantes :", + "items": [ + "Nom et portée du journal : saisissez un nom descriptif ; activez Apply trail to all accounts in my organization si vous avez besoin d'une collecte à l'échelle de l'organisation.", + "Destination S3 : choisissez Create new S3 bucket (ou sélectionnez un bucket existant) pour la livraison des journaux bruts.", + "Chiffrement : activez Log file SSE-KMS et sélectionnez la clé KMS appropriée.", + "Validation des fichiers journaux : activez-la pour garantir l'intégrité des journaux livrés (recommandé).", + "CloudWatch Logs : activez la livraison vers CloudWatch, sélectionnez Use existing log group et saisissez le nom exact utmstack.", + "Rôle IAM : fournissez ou créez le rôle que CloudTrail assumera pour écrire dans S3 et publier dans CloudWatch." + ] + }, + "eventTypes": { + "title": "Sélectionner les types d'événements", + "body": "Activez les catégories d'événements requises pour la surveillance et l'audit.", + "management": { + "label": "1 · Événements de gestion", + "body": "Activez Management events et sélectionnez All pour enregistrer toute l'activité API gérant les ressources AWS (création, mise à jour, suppression)." + }, + "data": { + "label": "2 · Événements de données", + "body": "Ajoutez un Data event. Choisissez S3 et sélectionnez Log all events pour capturer les opérations au niveau des objets, telles que GetObject et PutObject." + }, + "network": { + "label": "3 · Événements d'activité réseau", + "body": "Dans la section Network Activities, ajoutez au moins un service (ex. ec2.amazonaws.com) et activez Log all events." + } + }, + "review": { + "title": "Vérifier et créer le trail", + "body": "Sur l'écran Configure event aggregation, acceptez les valeurs par défaut (ou ajustez si nécessaire). Vérifiez tous les paramètres et cliquez sur Create trail." + } + } + }, + "crowdstrike": { + "intro": { + "title": "Fonctionnement", + "body": "UTMStack lit les détections et l'activité d'audit directement depuis l'API CrowdStrike Falcon Event Streams. Vous créez un client API dans Falcon avec la portée Event Streams ; UTMStack exécute un collecteur interne qui diffuse les événements en utilisant ces identifiants. Rien n'est installé sur vos endpoints ni dans Falcon.", + "diagram": { + "source": "détections & événements", + "edge1": "Event Streams API", + "api": "Falcon API", + "apiSub": "flux d'événements", + "edge2": "collecte", + "utmstackSub": "alertes & corrélation" + }, + "note": "UTMStack ne déploie aucun agent — il collecte les événements depuis Falcon en utilisant les identifiants du client API en lecture seule que vous fournissez ci-dessous." + }, + "sections": { + "apiClients": { + "title": "Ouvrir API Clients and Keys", + "body": "Dans la console Falcon, ouvrez le menu (icône hamburger, en haut à gauche) et accédez à Support and resources → API Clients and Keys." + }, + "createClient": { + "title": "Créer un nouveau client API", + "body": "Cliquez sur Create API Client pour démarrer la définition d'un nouveau client." + }, + "scopes": { + "title": "Nommer le client et accorder la portée Event Streams", + "body": "Donnez au client un nom descriptif (UTMStack l'utilise pour identifier la source d'événements) et sélectionnez les portées API requises pour Event Streams. Cliquez sur Create pour générer les identifiants." + }, + "recordCredentials": { + "title": "Enregistrer les identifiants", + "body": "Copiez le Client ID, le Client Secret et le Base URL correspondant à votre région CrowdStrike. Le secret n'est affiché qu'une seule fois — conservez-le en lieu sûr. Vous les collerez tous trois dans le formulaire ci-dessous." + } + }, + "credentials": { + "title": "Configuration du client API", + "body": "Utilisez les identifiants des étapes précédentes pour configurer UTMStack. Vous pouvez ajouter plusieurs clients CrowdStrike en enregistrant des configurations supplémentaires.", + "mapping": { + "intro": "Référence des champs", + "appName": "Nom de l'application — le nom descriptif du client défini à l'étape 3 (identifie la source d'événements)", + "clientId": "Client ID — valeur enregistrée à l'étape 4", + "clientSecret": "Client Secret — valeur enregistrée à l'étape 4 (affiché une seule fois)", + "cloudRegionUrl": "Base URL — le point de terminaison de votre région, ex. https://api.crowdstrike.com (us-1), https://api.us-2.crowdstrike.com (us-2), https://api.eu-1.crowdstrike.com (eu-1)" + } + }, + "fields": { + "appName": { + "label": "Nom de l'application" + }, + "clientId": { + "label": "Client ID" + }, + "clientSecret": { + "label": "Client Secret" + }, + "cloudRegionUrl": { + "label": "Base URL (région cloud)" + } + } + } + }, + "custom": { + "whenTitle": "Quand l'utiliser", + "whenBody": "Quand votre source n'est pas dans le catalogue. Transférez syslog ou JSON arbitraire à UTMStack et définissez un analyseur pour normaliser les champs.", + "endpointsTitle": "Points d'accès", + "syslogUdp": "Syslog (UDP)", + "syslogTls": "Syslog (TLS)", + "httpJson": "HTTP / JSON", + "payloadTitle": "Exemple de payload JSON", + "parserTitle": "Définir l'analyseur", + "parserBody": "Les événements entrants sont stockés sous le type de données {{dataType}}. Ajoutez un filtre d'analyse afin que la charge utile brute soit mappée en champs structurés, puis créez des règles d'alerte par-dessus.", + "openEditor": "Ouvrir l'éditeur d'analyseur", + "powershellLabel": "PowerShell (Exécuter en tant qu'administrateur)", + "linuxLabel": "Linux — bash", + "macosLabel": "macOS — bash", + "exampleLabel": "Exemple de cible syslog sur {{name}} :", + "intro": { + "title": "Fonctionnement", + "body": "Une intégration personnalisée ingère des journaux depuis toute source non couverte par les modules intégrés. Vous installez le UTMStack Collector, enregistrez un écouteur pour vos données avec le protocole de votre choix, puis pointez votre source vers celui-ci.", + "note": "Choisissez ci-dessous le protocole que votre source peut envoyer (syslog UDP/TCP/TLS, ou HTTP/HTTPS pour JSON) — le Collector crée le type de données automatiquement." + }, + "diagram": { + "source": "Votre source", + "sourceSub": "toute application ou appareil", + "forwarder": "Collector", + "ingests": "ingère", + "utmstackSub": "alertes & corrélation" + }, + "choose": { + "title": "Choisir le protocole et le port", + "body": "Sélectionnez la façon dont votre source envoie les données et le port sur lequel le Collector doit écouter, puis exécutez la commande d'activation sur l'hôte Collector.", + "portLabel": "Port d'écoute", + "tlsFirst": "Chargez d'abord votre certificat TLS et votre clé sur le Collector :", + "enableLabel": "Activez ensuite l'intégration :", + "authNote": "Pour exiger une authentification, ajoutez --auth bearer (jeton) ou --auth hmac — le Collector affiche un jeton à utiliser dans l'en-tête Authorization." + }, + "send": { + "title": "Pointer votre source vers le Collector", + "bodyNetwork": "Configurez votre source pour envoyer les journaux syslog {{proto}} vers {{host}}:{{port}}. La plupart des appareils disposent d'un paramètre syslog distant ou de transfert de journaux à cet effet.", + "bodyHttp": "Envoyez vos événements au format JSON via HTTP POST vers {{endpoint}}. Chaque corps de requête est un événement JSON :", + "httpBindNote": "L'écouteur HTTP/HTTPS est lié à 127.0.0.1 (l'hôte Collector) par défaut ; envoyez donc les requêtes depuis une application s'exécutant sur cet hôte, ou placez un proxy inverse devant. Pour les sources distantes, utilisez syslog (UDP/TCP/TLS)." + }, + "manualCommand": { + "title": "Optional — Enable via the command line instead", + "intro": "Prefer the terminal? SSH into the Collector host and run the command below — it matches whatever protocol and port you have selected above." + } + }, + "remoteEnable": { + "title": "Activer cette intégration à distance", + "body": "Choisissez un Collector, sélectionnez le protocole et le port, puis activez l'intégration — aucun SSH requis.", + "noPermission": "Vous n'avez pas la permission de gérer les intégrations distantes. Demandez à un administrateur d'accorder la permission integrations.write.", + "loadingCollectors": "Chargement des Collectors…", + "noCollectors": "Aucun Collector n'est enregistré pour le moment. Installez-en un ci-dessus pour activer les intégrations à distance.", + "forwarderOffline": "Ce Collector est hors ligne et ne peut pas recevoir de modifications de configuration en ce moment.", + "legendOnline": "{{count}} en ligne", + "legendOffline": "{{count}} hors ligne", + "legendTotal": "{{count}} total", + "forwarderLabel": "Collector", + "protoLabel": "Protocole", + "portLabel": "Port", + "currentStateLoading": "Vérification de la configuration actuelle…", + "currentlyEnabled": "Actuellement : activé · {{proto}} · port {{port}}", + "currentlyDisabled": "Actuellement : désactivé · {{proto}} · port {{port}}", + "authLabel": "Authentification", + "authNone": "Aucune", + "authBearer": "Jeton Bearer", + "authHmac": "Signature HMAC", + "pathLabel": "Chemin", + "signatureHeaderLabel": "En-tête de signature", + "certTitle": "Certificat TLS", + "certLoading": "Vérification du statut du certificat…", + "certLoaded": "Un certificat valide est déjà chargé sur ce Collector.", + "certMissing": "Aucun certificat chargé pour le moment — téléchargez-en un pour activer ce protocole.", + "certInvalid": "Le certificat chargé est invalide : {{error}}", + "certPemLabel": "Certificat", + "keyPemLabel": "Clé privée", + "caPemLabel": "Certificat CA", + "uploadCertsButton": "Télécharger le certificat", + "certUploadSuccess": "Certificat téléchargé.", + "certUploadError": "Échec du téléchargement du certificat.", + "certReadError": "Impossible de lire le(s) fichier(s) sélectionné(s).", + "enableButton": "Activer l'intégration", + "disableButton": "Désactiver l'intégration", + "enableSuccess": "Intégration activée.", + "disableSuccess": "Intégration désactivée.", + "enableError": "Échec de la mise à jour de l'intégration.", + "secretWarning": "Stockez ce jeton en toute sécurité — il ne sera pas affiché à nouveau.", + "sendToInstance": "Envoyer à l'instance", + "enterpriseFeature": "Ceci est une fonctionnalité Enterprise.", + "addCollector": "Ajouter un Collector", + "addApiKey": "Ajouter une clé API", + "apiKeyLabel": "Clé API", + "apiKeyHint": "Vous aurez d'abord besoin d'une clé API.", + "apiKeyPlaceholder": "Sélectionner une clé API", + "apiKeyAddNew": "Ajouter une clé API…", + "apiKeyNone": "Aucune clé API pour l'instant", + "forwarderNoRemoteControl": "Ce forwarder a été installé avec le contrôle à distance désactivé. Il ignore la configuration envoyée d'ici, et cela ne peut être modifié que sur la machine elle-même." + } + }, + "codeBlock": { + "copy": "Copier", + "copied": "Copié" + }, + "createDrawer": { + "title": "Nouvelle intégration personnalisée", + "moduleName": "Nom du module", + "moduleNameHint": "Identificateur unique. Sans espaces.", + "moduleNamePlaceholder": "ma-app-personnalisee", + "prettyName": "Nom d'affichage", + "prettyNamePlaceholder": "Ma App Personnalisée", + "dataType": "Type de données", + "dataTypePlaceholder": "Identificateur unique pour ce type de données", + "icon": "Icône", + "iconHint": "PNG, SVG, JPEG, GIF ou WEBP. Maximum 3 MB. Utilisé comme logo d'intégration.", + "iconPreview": "Aperçu de l'icône", + "dataTypeExists": "Ce type de données existe déjà", + "invalidFileType": "L'icône doit être un fichier image valide (PNG, JPEG, SVG, GIF, WEBP)", + "fileTooLarge": "L'icône ne doit pas dépasser 3 MB", + "fileReadError": "Échec de la lecture du fichier", + "cancel": "Annuler", + "create": "Créer l'intégration", + "creating": "Création…", + "editTitle": "Modifier l'intégration", + "save": "Enregistrer", + "saving": "Enregistrement…", + "currentIcon": "Icône actuelle — importez un fichier pour la remplacer", + "name": "Nom de l'intégration", + "namePlaceholder": "ex. Acme Firewall", + "description": "Description", + "descriptionPlaceholder": "Ce que cette intégration ingère et pourquoi (facultatif)", + "identifierHint": "Stocké sous “{{id}}” (dérivé du nom)", + "nameTaken": "Ce nom d'intégration ne peut pas être utilisé — une intégration avec cet identifiant existe déjà.", + "removeIcon": "Supprimer l'icône", + "defaultIconNote": "Icône par défaut — importez un fichier pour utiliser la vôtre." + }, + "toast": { + "created": "Intégration créée", + "updated": "Intégration mise à jour", + "updateError": "Échec de la mise à jour de l'intégration" + }, + "delete": { + "title": "Supprimer l'intégration", + "confirm": "Supprimer cette intégration ?", + "yes": "Supprimer", + "no": "Annuler", + "deleted": "Intégration supprimée", + "error": "Échec de la suppression de l'intégration" + }, + "modules": { + "WINDOWS_AGENT": "Collectez l'activité système, sécurité et journaux d'événements Windows via l'agent léger UTMStack installé sur chaque hôte.", + "LINUX_AGENT": "Collectez les journaux système, d'authentification et d'audit Linux via l'agent léger UTMStack installé sur chaque hôte.", + "MACOS": "Collectez l'activité des journaux système et sécurité macOS depuis les endpoints Apple Mac via l'agent léger UTMStack.", + "VMWARE": "Ingérez le syslog de l'hyperviseur VMware ESXi afin que l'activité et les événements des hôtes de virtualisation soient surveillés dans UTMStack.", + "NETFLOW": "Ingérez les enregistrements NetFlow provenant des routeurs et commutateurs pour surveiller les schémas de trafic réseau et détecter les anomalies.", + "AWS_IAM_USER": "Ingérez l'activité des comptes AWS et les appels API via CloudTrail et CloudWatch pour auditer l'utilisation, les accès et les modifications dans le cloud.", + "AZURE": "Ingérez les journaux de plateforme et d'activité Microsoft Azure pour surveiller les charges de travail cloud, les identités et les modifications de ressources.", + "O365": "Ingérez les journaux d'audit Microsoft 365 couvrant Exchange, Teams, SharePoint et OneDrive pour surveiller l'activité des utilisateurs et des administrateurs.", + "O365_GRAPH": "Ingeste les événements de sécurité Microsoft Graph — alertes, incidents, audit du répertoire, sign-ins, détections de risque et journaux Purview — pour surveiller l'identité et les menaces dans votre tenant.", + "GCP": "Ingérez les journaux d'audit et d'activité Google Cloud Platform pour surveiller le calcul, le stockage et les identités dans vos projets.", + "KASPERSKY": "Ingérez les détections et la télémétrie des endpoints Kaspersky Security Center pour corréler l'activité des logiciels malveillants sur le réseau.", + "ESET": "Ingérez les détections et la télémétrie des endpoints ESET PROTECT pour corréler la défense multicouche contre les logiciels malveillants sur votre parc.", + "BITDEFENDER": "Ingérez les détections et la télémétrie des endpoints Bitdefender GravityZone pour corréler les menaces sur les appareils professionnels.", + "SENTINEL_ONE": "Ingérez les détections et la télémétrie comportementale des endpoints SentinelOne pour corréler et investiguer les menaces à grande échelle.", + "SOPHOS": "Ingérez les détections Sophos Central couvrant les endpoints, serveurs, pare-feu et messagerie pour corréler les menaces en un seul endroit.", + "CROWDSTRIKE": "Ingérez les détections CrowdStrike Falcon des endpoints et des charges de travail pour corréler l'activité des menaces cloud-native dans UTMStack.", + "CISCO": "Ingérez les journaux de trafic, VPN et menaces du pare-feu Cisco ASA pour surveiller la sécurité périmétrique et les accès dans UTMStack.", + "MERAKI": "Ingérez le syslog des pare-feu et appliances de sécurité Cisco Meraki pour surveiller le trafic réseau géré dans le cloud et les menaces.", + "FIRE_POWER": "Ingérez les journaux Cisco Firepower NGFW et IPS pour surveiller les tentatives d'intrusion et l'activité des menaces en périmètre.", + "CISCO_SWITCH": "Ingérez le syslog et la télémétrie des commutateurs Cisco pour surveiller les performances réseau, les modifications de configuration et la sécurité.", + "FORTIGATE": "Ingérez les journaux de trafic et de menaces Fortinet FortiGate NGFW pour surveiller la sécurité périmétrique et l'activité réseau.", + "FORTIWEB": "Ingérez les journaux Fortinet FortiWeb WAF pour surveiller les attaques contre les applications web et protéger les services et API exposés.", + "SOPHOS_XG": "Ingérez les journaux du pare-feu Sophos XG couvrant le filtrage web, l'IPS et le VPN pour surveiller le trafic réseau et les menaces.", + "PALO_ALTO": "Ingérez les journaux de trafic et de menaces Palo Alto Networks NGFW pour surveiller l'utilisation des applications et la sécurité périmétrique.", + "SONIC_WALL": "Ingérez les journaux de trafic et de menaces SonicWall NGFW pour surveiller la sécurité périmétrique et l'activité réseau dans UTMStack.", + "PFSENSE": "Ingérez les journaux de pare-feu et de routeur pfSense avec la gestion unifiée des menaces pour surveiller le trafic réseau et les menaces.", + "MIKROTIK": "Ingérez les journaux de pare-feu, de routage et sans fil MikroTik RouterOS pour surveiller l'activité réseau et la configuration.", + "AIX": "Collectez les journaux système, sécurité et d'audit IBM AIX Unix pour surveiller l'activité sur les plateformes IBM Power dans UTMStack.", + "AS_400": "Collectez les journaux système et d'audit IBM AS/400 (IBM i) pour surveiller l'activité des utilisateurs sur les plateformes midrange OS/400.", + "ORACLE": "Ingérez les journaux d'audit Oracle Database pour surveiller les requêtes, les accès et les activités privilégiées sur vos bases de données.", + "SURICATA": "Ingérez les alertes et événements réseau Suricata IDS/IPS pour détecter les intrusions et le trafic malveillant sur le réseau.", + "DECEPTIVE_BYTES": "Ingérez les alertes Deceptive Bytes depuis sa plateforme active de tromperie des endpoints pour détecter rapidement l'activité des attaquants.", + "GITHUB": "Ingérez les journaux d'audit GitHub pour surveiller les accès aux dépôts, les modifications de code et l'activité de l'organisation pour la sécurité des sources.", + "UTMSTACK": "Ingérez la télémétrie SIEM et XDR propre à UTMStack pour surveiller la santé de la plateforme, l'activité interne et les événements d'auto-audit.", + "NGINX": { + "name": "Nginx", + "description": "Ingérez les journaux d'accès et d'erreur de Nginx pour surveiller l'activité du serveur web, le trafic du proxy inverse et les requêtes des clients." + }, + "APACHE": { + "name": "Apache", + "description": "Ingérez les journaux d'accès et d'erreur d'Apache HTTPD pour surveiller l'activité du serveur web et les requêtes des clients." + }, + "APACHE2": { + "name": "Apache2", + "description": "Ingérez les journaux du serveur web Apache2 (HTTPD) pour surveiller le traitement des requêtes, les erreurs et l'accès sur les hôtes Linux." + }, + "IIS": { + "name": "IIS", + "description": "Ingérez l'activité d'accès et les fichiers journaux d'Internet Information Services (IIS) pour surveiller le service web Windows." + }, + "MYSQL": { + "name": "MySQL", + "description": "Ingérez l'activité des journaux MySQL pour surveiller les requêtes, l'authentification et l'accès au magasin de données." + }, + "POSTGRESQL": { + "name": "PostgreSQL", + "description": "Ingérez les journaux PostgreSQL pour surveiller les requêtes, l'accès et l'activité de vos magasins de données." + }, + "MONGODB": { + "name": "MongoDB", + "description": "Ingérez l'activité des journaux MongoDB pour surveiller l'accès à la base de données documentaire, les requêtes et le comportement de l'application." + }, + "REDIS": { + "name": "Redis", + "description": "Ingérez l'activité des journaux et de la télémétrie Redis pour surveiller l'utilisation du magasin de données en mémoire et les charges de travail en temps réel." + }, + "ELASTICSEARCH": { + "name": "Elasticsearch", + "description": "Ingérez les journaux Elasticsearch pour surveiller le moteur de recherche et d'analyse et ses charges de travail applicatives." + }, + "LOGSTASH": { + "name": "Logstash", + "description": "Ingérez les journaux des pipelines Logstash pour surveiller le pipeline de traitement des données et ses transformations d'événements." + }, + "KIBANA": { + "name": "Kibana", + "description": "Ingérez les journaux Kibana pour surveiller la couche de visualisation et d'exploration des données et son utilisation." + }, + "KAFKA": { + "name": "Apache Kafka", + "description": "Ingérez les journaux Apache Kafka pour surveiller les pipelines de streaming en temps réel, les brokers et le flux de messages." + }, + "NATS": { + "name": "NATS", + "description": "Ingérez les journaux de messagerie NATS pour surveiller le bus de messages, la connectivité et la livraison des événements." + }, + "HAPROXY": { + "name": "HAProxy", + "description": "Ingérez les journaux HAProxy pour surveiller l'équilibrage de charge, le trafic du proxy et la disponibilité du réseau." + }, + "TRAEFIK": { + "name": "Traefik", + "description": "Ingérez les journaux Traefik pour surveiller le routage, l'équilibrage de charge et le trafic du proxy entre les charges de travail." + }, + "OSQUERY": { + "name": "osquery", + "description": "Ingérez les journaux OsQuery pour surveiller l'état des terminaux, les requêtes et l'inventaire du système via des requêtes au style SQL." + }, + "SYSLOG": { + "name": "Syslog", + "description": "Envoyez le syslog (RFC 5424/3164) de n'importe quel appareil ou application vers le point d'accès du collecteur pour une prise en charge centralisée des journaux." + }, + "JSON": { + "name": "JSON Input", + "description": "Envoyez des charges de journaux JSON vers le point d'ingestion pour une prise en charge structurée des événements d'applications et de scripts." + }, + "WINDOWS_SQL_SERVER": { + "name": "SQL Server Event Logs", + "description": "Collect Microsoft SQL Server audit and event records through the Windows Event Log and UTMStack agent." + }, + "WINDOWS_FILE_AUDITING": { + "name": "Windows File Access Auditing", + "description": "Collect Windows file access audit events through the Windows Event Log and UTMStack agent." + }, + "ELASTICsearch": { + "name": "ELASTICsearch", + "description": "Ingesta los registros de Elasticsearch para monitorear el motor de búsqueda y análisis y sus cargas de trabajo de aplicación." + } + }, + "edit": { + "title": "Modifier l'intégration" + }, + "allCategories": "Toutes les catégories", + "customOnly": "Personnalisé" + }, + "dataProcessing": { + "title": "Traitement des données", + "subtitle": "Statistiques d’ingestion et de traitement : événements reçus, rejetés par étape, et les principales sources et types.", + "ingestion": { + "title": "Ingestion", + "last24h": "dernières 24 heures", + "noData": "Aucune donnée sur cette fenêtre.", + "loadError": "Impossible de charger les statistiques d’ingestion.", + "groupBy": { + "dataSource": "Par source de données", + "dataType": "Par type de données" + }, + "status": { + "received": "Reçus", + "parsing_dropped": "Rejetés (analyse syntaxique)", + "analysis_dropped": "Rejetés (analyse)", + "correlation_dropped": "Rejetés (corrélation)", + "all": "Tous les événements" + } + }, + "filters": { + "title": "Filtres", + "new": "Nouveau filtre", + "search": "Rechercher par chemin…", + "refresh": "Actualiser", + "retry": "Réessayer", + "empty": "Aucun filtre ne correspond.", + "loadError": "Impossible de charger les filtres.", + "toggleError": "Impossible de changer l’état du filtre", + "system": "Système", + "custom": "Personnalisé", + "systemReadonly": "Les filtres système sont en lecture seule", + "view": "Voir", + "edit": "Modifier", + "ownership": { + "all": "Tous", + "system": "Système", + "custom": "Personnalisés" + }, + "state": { + "all": "Tous", + "active": "Actifs", + "inactive": "Inactifs" + }, + "col": { + "filter": "Filtre", + "type": "Type", + "active": "Actif", + "actions": "Actions" + }, + "pageInfo": "{{from}}–{{to}} sur {{count}}" + }, + "editor": { + "createTitle": "Nouveau filtre", + "editTitle": "Modifier le filtre", + "viewTitle": "Voir le filtre", + "relPath": "Chemin", + "relPathHint": "Dossier + fichier, p. ex. syslog/mon-filtre.yaml", + "content": "Pipeline (YAML)", + "contentHint": "Les étapes s’exécutent dans l’ordre : grok, rename, delete, plugins dynamic, …", + "save": "Enregistrer", + "saving": "Enregistrement…", + "saved": "Filtre enregistré", + "saveError": "Impossible d’enregistrer le filtre", + "cancel": "Annuler", + "delete": "Supprimer", + "deleteConfirm": "Supprimer ce filtre ?", + "deleted": "Filtre supprimé", + "deleteError": "Impossible de supprimer le filtre" + }, + "kpi": { + "received": "Reçus", + "dropped": "Rejetés", + "dropRate": "{{rate}} % de rejet", + "stored": "Stockés", + "throughput": "Débit", + "perMin": "{{value}}/min", + "survival": "{{rate}}% conservés" + }, + "section": { + "overTime": "Événements dans le temps", + "top": "Top", + "dropReasons": "Motifs de rejet" + }, + "live": { + "auto": "Auto" + }, + "pipeline": { + "title": "Pipeline d’ingestion", + "stages": { + "received": "Reçus", + "parsed": "Analysés (parse)", + "analyzed": "Analysés", + "stored": "Stockés" + } + }, + "chart": { + "title": "Débit dans le temps", + "received": "Reçus", + "dropped": "Rejetés" + }, + "donut": { + "title": "Composition des rejets", + "dropped": "rejetés" + }, + "breakdown": { + "title": "Top sources et types", + "bars": "Barres", + "treemap": "Treemap", + "showAll": "Afficher les {{count}}", + "showLess": "Afficher moins", + "lastSeen": "Vu pour la dernière fois", + "ago": "il y a {{time}}" + } }, - "compliance": "Conformité", - "configure": "Configurer", - "dataSources": "Sources de données", - "integrations": "Intégrations", - "alertingRules": "Règles d'alerte", - "dataProcessing": "Traitement des données", - "team": "Équipe", - "settings": "Paramètres", - "back": "Retour", - "regexPatterns": "Expressions régulières", - "taggingRules": "Règles d'étiquetage", - "parsingFilters": "Pipelines", - "overview": "Vue d'ensemble", - "tenants": "Locataires", - "openMenu": "Ouvrir le menu", - "closeMenu": "Fermer le menu", - "liveOps": "Opérations en direct" - }, - "dashboards": { - "title": "Tableaux de bord", - "subtitle": "Parcourez et modifiez des tableaux de bord interactifs.", - "list": { - "title": "Tableaux de bord", - "create": "Nouveau", - "searchPlaceholder": "Rechercher des tableaux de bord…", - "loading": "Chargement des tableaux de bord…", - "empty": "Aucun tableau de bord pour le moment.", - "rename": "Renommer", - "delete": "Supprimer" + "datasources": { + "limitBanner": { + "title": "Limite de sources de données dépassée.", + "message": "Vous avez {{count}} sources de données mais votre licence en couvre {{limit}}. Les journaux des sources au-delà de la limite sont rejetés.", + "cta": "Gérer la licence", + "dismiss": "Ignorer" + }, + "title": "Sources de données", + "total": "{{count}} au total", + "subtitle": "Agents, intégrations et sources directes qui envoient des événements. Le statut est dérivé de la dernière fois que chaque source a été vue.", + "connectSource": "Connecter une source", + "loading": "Chargement des sources de données…", + "loadFailed": "Impossible de charger les sources de données.", + "retry": "Réessayer", + "none": "Aucune source ne correspond à cette vue.", + "ingestion": { + "title": "Ingestion", + "received": "événements reçus", + "none": "Aucune ingestion ces dernières 24 heures.", + "ago24h": "il y a 24h", + "now": "maintenant" + }, + "usage": { + "title": "Sources de données", + "ofUnlimited": "sur illimité", + "ofLimit": "sur {{limit}}", + "overLimit": "Au-delà de la limite sous licence — les données au-delà du plafond sont à risque.", + "configured": "configurées" + }, + "tabs": { + "all": "Toutes", + "agent": "Agents", + "puller": "Intégrations", + "direct": "Directes", + "offline": "Hors ligne" + }, + "toolbar": { + "searchPlaceholder": "Rechercher par nom…", + "list": "Liste", + "cards": "Cartes", + "refresh": "Actualiser" + }, + "labels": { + "filteredBy": "Filtré par label", + "add": "Ajouter un label…", + "addFirst": "Ajouter un label…", + "hint": "Saisissez un label et appuyez sur Entrée pour l'ajouter. Les modifications sont enregistrées automatiquement." + }, + "status": { + "live": "Actif", + "idle": "Inactif", + "offline": "Hors ligne" + }, + "kind": { + "agent": "Agent", + "puller": "Intégration", + "direct": "Directe" + }, + "cols": { + "source": "Source", + "type": "Type", + "status": "Statut", + "events24h": "Événements 24h", + "lastSeen": "Vu pour la dernière fois" + }, + "time": { + "justNow": "à l'instant", + "minutesAgo": "il y a {{count}}m", + "hoursAgo": "il y a {{count}}h", + "daysAgo": "il y a {{count}}j" + }, + "drawer": { + "loading": "Chargement…", + "loadFailed": "Impossible de charger la source de données.", + "statsIdentity": "Stats et identité", + "metadata": "Métadonnées", + "labelsSection": "Labels", + "dangerZone": "Zone de danger", + "rows": { + "events24h": "Événements 24h", + "lastSeen": "Vu pour la dernière fois", + "discovered": "Découverte", + "kind": "Type d'origine", + "dataType": "Type de donnée", + "ip": "IP", + "id": "ID" + }, + "dangerText": "La suppression retire cette source du registre. Les événements historiques restent consultables dans le Log Explorer ; si la source continue d'envoyer des données, elle sera redécouverte.", + "delete": "Supprimer la source", + "confirmDelete": "Confirmer la suppression", + "cancel": "Annuler", + "viewLogs": "Voir les journaux", + "trend": "Tendance d'ingestion", + "noTrend": "Aucun événement reçu sur cette période", + "logGap": "Dernier événement {{since}} — interruption possible des journaux" + }, + "toast": { + "labelsUpdated": "Labels mis à jour", + "labelsFailed": "Échec de la mise à jour des labels", + "deleted": "Source supprimée", + "deleteFailed": "Échec de la suppression" + }, + "sensitivity": { + "section": "Sensibilité de l'actif", + "hint": "Criticité métier (CIA, 0–3) de cet actif. Les alertes ciblant son hôte/IP sont pondérées par ces valeurs.", + "saved": "Sensibilité mise à jour", + "failed": "Échec de la mise à jour de la sensibilité", + "save": "Enregistrer", + "confidentiality": "Confidentialité", + "integrity": "Intégrité", + "availability": "Disponibilité", + "levels": { + "0": "Aucune", + "1": "Faible", + "2": "Moyenne", + "3": "Élevée" + } + }, + "console": { + "section": "Console", + "sectionHint": "Exécuter des commandes sur cet hôte via son agent (réponse en direct).", + "open": "Ouvrir la console", + "close": "Fermer", + "hint": "Saisissez une commande et appuyez sur Entrée pour l'exécuter sur l'agent.", + "running": "Exécution…", + "placeholder": "Saisissez une commande…", + "offline": "Cet agent semble hors ligne — il pourrait ne pas répondre aux commandes.", + "vars": { + "button": "Variables", + "title": "Variables de commande", + "subtitle": "Référencez-les dans les commandes sous la forme", + "add": "Nouvelle variable", + "name": "Nom", + "value": "Valeur", + "description": "Description", + "isSecret": "Secret (chiffré, masqué dans la sortie)", + "secret": "secret", + "secretHint": "Laissez vide pour conserver la valeur enregistrée.", + "save": "Enregistrer", + "cancel": "Annuler", + "edit": "Modifier", + "delete": "Supprimer", + "loading": "Chargement…", + "empty": "Aucune variable pour l'instant.", + "saved": "Variable enregistrée", + "deleted": "Variable supprimée", + "nameRequired": "Le nom est requis", + "loadError": "Échec du chargement des variables", + "saveError": "Échec de l'enregistrement de la variable", + "deleteError": "Échec de la suppression de la variable", + "insert": "Insérer", + "valueRequired": "Une valeur est requise" + }, + "disabled": "Agent hors ligne — commandes désactivées", + "connError": "Erreur de connexion", + "cmdError": "Erreur de commande", + "shellSelect": "Type de shell", + "noRemoteControl": "Cet agent a été installé avec le contrôle à distance désactivé. Il refuse les commandes, et cela ne peut être modifié que sur la machine elle-même.", + "noRemoteControlShort": "Contrôle à distance désactivé sur cet agent", + "password": { + "title": "Authentification", + "hint": "S'authentifier pour exécuter des commandes sur cet agent.", + "tfaPrompt": "Code: ", + "confirm": "OK", + "cancel": "Annuler", + "authError": "Échec de l'authentification", + "authHint": "S'authentifier pour exécuter des commandes sur cet agent.", + "authOk": "Authentifié." + } + }, + "health": { + "online": "en ligne", + "offline": "hors ligne", + "total": "total" + } }, - "actions": { - "edit": "Modifier", - "editWithAi": "Modifier avec l'IA" + "adversaries": { + "title": "Vue des adversaires", + "subtitle": "Chaque IP, hôte ou utilisateur vu attaquer votre environnement, avec leurs techniques et cibles.", + "countChip": "{{count}} adversaires", + "refresh": "Actualiser", + "search": "Rechercher par IP, hôte, utilisateur, pays, ASO…", + "empty": "Aucun adversaire ne correspond.", + "loadError": "Impossible de charger les adversaires.", + "retry": "Réessayer", + "views": { + "all": "Tous", + "high": "Sévérité élevée", + "ip": "IP", + "host": "Hôtes", + "user": "Utilisateurs" + }, + "threat": { + "critical": "Critique", + "high": "Élevé", + "medium": "Moyen", + "low": "Faible" + }, + "kind": { + "ip": "IP", + "host": "Hôte", + "user": "Utilisateur" + }, + "layout": { + "list": "Liste", + "cards": "Cartes" + }, + "overview": { + "title": "Activité des adversaires · dernières 24 heures", + "high": "sévérité élevée", + "countries": "pays", + "alerts": "alertes", + "ago24": "il y a 24h", + "ago12": "il y a 12h", + "now": "maintenant" + }, + "col": { + "adversary": "Adversaire", + "threat": "Menace", + "alerts": "Alertes", + "targets": "Cibles", + "lastSeen": "Vu pour la dernière fois", + "victims": "Victimes" + }, + "card": { + "alerts": "Alertes", + "techniques": "Techniques", + "targets": "Cibles" + }, + "tabs": { + "profile": "Profil", + "techniques": "Techniques", + "targets": "Cibles", + "alerts": "Alertes" + }, + "drawer": { + "activity": "Activité sur 24 heures", + "identification": "Identification", + "kindLabel": "Type", + "identifier": "Identifiant", + "firstSeen": "Vu pour la première fois", + "lastSeen": "Vu pour la dernière fois", + "geolocation": "Géolocalisation", + "country": "Pays", + "city": "Ville", + "topTechniques": "Principales techniques", + "noTechniques": "Aucune technique enregistrée.", + "targets": "Cibles", + "noTargets": "Aucune cible enregistrée.", + "recentAlerts": "Alertes récentes", + "noAlerts": "Aucune alerte.", + "echoes": "{{count}} répétitions" + }, + "relative": { + "justNow": "à l’instant", + "minutesAgo": "il y a {{count}}m", + "hoursAgo": "il y a {{count}}h", + "daysAgo": "il y a {{count}}j" + }, + "field": { + "ip": "IP", + "host": "Hôte", + "user": "Utilisateur", + "port": "Port", + "domain": "Domaine", + "mac": "MAC", + "country": "Pays", + "city": "Ville", + "asn": "ASN", + "aso": "ASO" + } }, - "refresh": { - "title": "Actualisation automatique", - "options": { - "off": "Désactivé", - "10s": "10s", - "30s": "30s", - "1m": "1m", - "5m": "5m", - "15m": "15m" - } + "timeRange": { + "quick": "Plages rapides", + "relative": "Relatif", + "absolute": "Absolu", + "last": "Derniers", + "apply": "Appliquer", + "allTime": "Toute la période", + "from": "De", + "to": "À", + "now": "maintenant", + "units": { + "minutes": "minutes", + "hours": "heures", + "days": "jours", + "weeks": "semaines", + "months": "mois" + }, + "presets": { + "15m": "15 dernières minutes", + "1h": "Dernière heure", + "6h": "6 dernières heures", + "24h": "24 dernières heures", + "7d": "7 derniers jours", + "30d": "30 derniers jours" + } }, - "editor": { - "editing": "Édition", - "addWidget": "Ajouter un widget", - "save": "Enregistrer", - "discard": "Annuler", - "newTitle": "Nouveau widget", - "newSubtitle": "Choisissez un type de graphique, une source de données et mettez-le en forme visuellement. La requête SQL est générée automatiquement.", - "editTitle": "Modifier le widget", - "editSubtitle": "Ajustez la définition du graphique. Les modifications s'appliquent partout où ce widget est utilisé.", - "loading": "Chargement du widget…", - "notFoundTitle": "Widget introuvable", - "notFoundSubtitle": "Elle a peut-être été supprimée ou vous n'y avez pas accès.", - "backToDashboard": "Retour au tableau de bord", - "chartType": { - "title": "Type de graphique" - }, - "chartTypes": { - "bar": { - "label": "Barres", - "description": "Comparer des valeurs entre catégories." - }, - "line": { - "label": "Courbe", - "description": "Tendances sur un axe ordonné." - }, - "area": { - "label": "Aire", - "description": "Courbe remplie — met en valeur le volume." - }, - "pie": { - "label": "Camembert", - "description": "Part d'un total par catégorie." - }, - "metric": { - "label": "Métrique", - "description": "Une valeur scalaire unique." + "alerts": { + "title": "Alertes", + "matching": "{{count}} correspondances", + "subtitle": "Triez ce qui compte.", + "openNow": "ouvertes actuellement.", + "view": { + "alerts": "Alertes", + "overview": "Aperçu" + }, + "toolbar": { + "searchPlaceholder": "Rechercher par nom d'alerte…", + "allSeverities": "Toutes les sévérités", + "export": "Exporter en CSV", + "refresh": "Actualiser" + }, + "severity": { + "high": "Élevée", + "medium": "Moyenne", + "low": "Faible" + }, + "status": { + "open": "Ouverte", + "in_review": "En cours de revue", + "completed": "Terminée", + "auto": "Revue automatique" + }, + "statusTabs": { + "all": "Toutes" + }, + "overview": { + "overTime": "Alertes dans le temps", + "matchingAlerts": "alertes correspondantes", + "noData": "Aucune donnée.", + "bySeverity": "Par sévérité", + "byStatus": "Par statut" + }, + "filters": { + "add": "Ajouter un filtre", + "clearAll": "Tout effacer", + "filterValues": "Filtrer les valeurs…", + "loadingValues": "Chargement des valeurs…", + "noValues": "Aucune valeur trouvée.", + "pickValue": "Choisissez une valeur pour ajouter le filtre.", + "empty": "(vide)", + "cancel": "Annuler", + "addBtn": "Ajouter" + }, + "ops": { + "CONTAIN": "contient", + "IS": "est", + "IS_NOT": "n'est pas", + "EXIST": "existe", + "DOES_NOT_EXIST": "n'existe pas" + }, + "fields": { + "adversary_domain": "Domaine de l'adversaire", + "adversary_geolocation_asn": "ASN de l'adversaire", + "adversary_geolocation_aso": "ASO de l'adversaire", + "adversary_geolocation_country": "Pays de l'adversaire", + "adversary_host": "Hôte de l'adversaire", + "adversary_ip": "IP de l'adversaire", + "adversary_url": "URL de l'adversaire", + "adversary_user": "Utilisateur de l'adversaire", + "assignee": "Assigné à", + "category": "Catégorie", + "dataSource": "Capteur", + "dataType": "Type de données", + "description": "Description", + "id": "ID", + "impactScore": "Risque", + "impact_availability": "Disponibilité", + "impact_confidentiality": "Confidentialité", + "impact_integrity": "Intégrité", + "incidentDetail_incidentName": "Nom de l'incident", + "incidentDetail_incidentId": "Id de l'incident", + "isIncident": "Est un incident", + "name": "Nom de l'alerte", + "notes": "Notes", + "severity": "Sévérité", + "status": "Statut", + "tags": "Étiquettes", + "target_domain": "Domaine de la cible", + "target_geolocation_asn": "ASN de la cible", + "target_geolocation_aso": "ASO de la cible", + "target_geolocation_country": "Pays de la cible", + "target_host": "Hôte de la cible", + "target_ip": "IP de la cible", + "target_url": "URL de la cible", + "target_user": "Utilisateur de la cible", + "technique": "Technique" + }, + "tagFilter": { + "tags": "Étiquettes", + "tag_one": "{{count}} étiquette", + "tag_other": "{{count}} étiquettes", + "clearSelection": "Effacer la sélection", + "noTags": "Pas d'étiquettes" + }, + "bulk": { + "selected": "{{count}} sélectionnées", + "setStatus": "Définir le statut", + "addTag": "Ajouter une étiquette", + "noTags": "Pas d'étiquettes", + "addToIncident": "Ajouter à un incident", + "clear": "Effacer" + }, + "tagEditor": { + "tag": "Étiquette", + "noTagsYet": "Pas encore d'étiquettes", + "createTag": "Créer une étiquette", + "newTagName": "Nom de la nouvelle étiquette…", + "createApply": "Créer et appliquer l’étiquette", + "save": "Enregistrer", + "cancel": "Annuler", + "edit": "Modifier l'étiquette", + "delete": "Supprimer l'étiquette", + "systemLocked": "Étiquette système (verrouillée)", + "alreadyExists": "Cette étiquette existe déjà.", + "color": "Couleur {{color}}", + "createRule": "Créer une règle d'étiquetage avec cette étiquette" }, "table": { - "label": "Tableau", - "description": "Lignes agrégées." + "actions": "Actions", + "alert": "Alerte", + "status": "Statut", + "technique": "Technique", + "severity": "Gravité", + "risk": "Risque", + "echoes": "Échos", + "time": "Heure", + "riskHint": "Score de risque (0–100), coloré selon la gravité", + "source": "Source", + "adversary": "Adversaire" + }, + "row": { + "createRuleFromAlert": "Créer une étiquette à partir de cette alerte", + "createIncident": "Créer un incident à partir de cette alerte", + "viewIncident": "Voir les détails de l'incident", + "assignedTo": "Attribuée à {{user}}", + "echoesTooltip": "{{count}} échos — cliquez pour développer", + "echoesEmpty": "Aucun écho enregistré" + }, + "echoes": { + "title": "{{count}} échos", + "close": "Fermer", + "empty": "Aucun écho enregistré pour cette alerte.", + "loadError": "Impossible de charger les échos." }, "list": { - "label": "Liste", - "description": "Lignes brutes, sans agrégation." + "loading": "Chargement des alertes…", + "loadError": "Impossible de charger les alertes.", + "retry": "Réessayer", + "empty": "Aucune alerte ne correspond à cette vue." + }, + "badge": { + "incident": "Incident", + "aiAssessed": "Évalué par IA" + }, + "drawer": { + "setStatus": "Définir le statut", + "completeFalsePositive": "Terminer + faux positif", + "addToIncident": "Ajouter à un incident", + "partOfIncident": "Partie d'un incident", + "tabs": { + "summary": "Résumé", + "parties": "Parties", + "events": "Événements", + "history": "Historique" + }, + "section": { + "description": "Description", + "solution": "Solution", + "references": "Références", + "details": "Détails", + "yourNotes": "Vos notes", + "notes": "Notes" + }, + "details": { + "severity": "Gravité", + "risk": "Risque", + "category": "Catégorie", + "technique": "Technique", + "sensor": "Capteur", + "dataType": "Type de donnée", + "alertId": "ID d'alerte", + "statusNote": "Note de statut", + "assignee": "Personne assignée" + }, + "incidentDetail": { + "incident": "Incident", + "id": "ID", + "createdBy": "Créé par", + "created": "Créé" + }, + "notesPlaceholder": "Ajouter des notes d'investigation…", + "saveNotes": "Enregistrer les notes", + "assignee": "Attribuer", + "assign": "Attribuer", + "unassign": "Désattribuer", + "unassigned": "Non attribuée", + "loadingUsers": "Chargement des utilisateurs…", + "observationLabel": "Observation", + "observationPlaceholder": "Ajouter une observation…", + "cancel": "Annuler", + "continue": "Continuer" + }, + "related": { + "sample": "Un échantillon de jusqu’à ~11 événements que le moteur a stockés sur cette alerte. Utilisez « Voir tous les journaux associés » pour l’ensemble complet et non plafonné.", + "loadingEchoes": "Chargement des événements de ses échos…", + "sampleWithEchoes": "Les événements stockés sur cette alerte et sur ses {{count}} échos ({{read}} lus). Utilisez « Voir tous les journaux associés » pour l’ensemble complet et non plafonné.", + "empty": "Aucun événement d’échantillon stocké sur cette alerte. Chargez l’ensemble corrélé complet dans l’Explorateur de journaux.", + "viewAll": "Voir tous les journaux associés" + }, + "party": { + "source": "Source / cible", + "adversary": "Adversaire", + "noData": "Aucune donnée.", + "ip": "IP", + "host": "Hôte", + "user": "Utilisateur", + "domain": "Domaine", + "country": "Pays" + }, + "history": { + "empty": "Aucun historique enregistré.", + "by": "par {{user}}", + "actions": { + "UPDATE_STATUS": "Statut mis à jour", + "UPDATE_TAGS": "Étiquettes mises à jour", + "UPDATE_NOTES": "Notes mises à jour", + "UPDATE_SOLUTION": "Solution mise à jour", + "MARK_AS_INCIDENT": "Marquée comme incident" + }, + "detail": { + "statusTo": "Statut → {{status}}", + "tags": "Étiquettes : {{tags}}", + "aiAdded": "Évaluation IA ajoutée", + "observationAdded": "Observation ajoutée", + "notesUpdated": "Notes mises à jour" + } + }, + "ai": { + "title": "Évaluation IA du SOC", + "risk": "risque {{risk}}", + "score": "{{score}}/100", + "generate": "Générer le résumé IA", + "hint": "SOC-AI analyse cette alerte et ajoute une évaluation.", + "generating": "Analyse de l'alerte en cours… cela peut prendre une minute.", + "ready": "Résumé IA prêt", + "failed": "Impossible de générer le résumé IA", + "slow": "Le résumé IA prend plus de temps que prévu. Il apparaîtra sur l'alerte dès qu'il sera prêt." }, - "region_map": { - "label": "Carte de coordonnées", - "description": "Placer des marqueurs sur une carte du monde à partir de coordonnées lat/lon." + "incident": { + "titleAdd_one": "Ajouter {{count}} alerte à un incident", + "titleAdd_other": "Ajouter {{count}} alertes à un incident", + "new": "Nouvel incident", + "existing": "Incident existant", + "nameLabel": "Nom de l'incident", + "namePlaceholder": "p. ex. Intrusion présumée de Scattered Spider", + "descriptionLabel": "Description", + "descriptionPlaceholder": "Résumé facultatif…", + "pickLabel": "Choisir un incident", + "loading": "Chargement…", + "selectPlaceholder": "Sélectionner un incident…", + "willLink_one": "{{count}} alerte sera liée.", + "willLink_other": "{{count}} alertes seront liées.", + "cancel": "Annuler", + "create": "Créer l'incident", + "add": "Ajouter à un incident" }, - "text": { - "label": "Texte", - "description": "Texte libre ou sortie ligne par ligne." + "toast": { + "statusUpdated": "Statut mis à jour", + "statusFailed": "Échec de la mise à jour du statut", + "tagsUpdated": "Étiquettes mises à jour", + "tagsFailed": "Échec de la mise à jour des étiquettes", + "tagCreateFailed": "Échec de la création de l'étiquette", + "tagUpdated": "Étiquette mise à jour", + "tagUpdateFailed": "Échec de la mise à jour de l'étiquette", + "tagDeleted": "Étiquette supprimée", + "tagDeleteFailed": "Échec de la suppression de l'étiquette", + "notesSaved": "Notes enregistrées", + "notesFailed": "Échec de l'enregistrement des notes", + "exportFailed": "Échec de l'export CSV", + "noRelatedLogs": "Aucun journal associé trouvé pour cette alerte", + "relatedLogsFailed": "Échec du chargement des journaux associés", + "incidentCreated": "Incident créé", + "alertsAdded": "Alertes ajoutées à l'incident", + "incidentFailed": "Échec de l'enregistrement de l'incident", + "assigned": "Alerte attribuée", + "unassigned": "Alerte désattribuée", + "assignFailed": "Impossible de mettre à jour l'attribution", + "newAlertsToast_title": "Nouvelles alertes", + "newAlertsToast_count_one": "{{count}} nouvelle alerte", + "newAlertsToast_count_other": "{{count}} nouvelles alertes", + "newAlertsToast_view": "Voir" } - }, - "dataSource": { - "title": "Quelles données ?", - "dataset": "Jeu de données", - "noDatasetHint": "Choisissez un jeu de données pour activer les conditions et le regroupement." - }, - "widgetTitle": { - "label": "Titre", - "placeholder": "Facultatif — par défaut, le type de graphique" - }, - "dataset": { - "placeholder": "Sélectionnez un jeu de données…", - "loading": "Chargement des jeux de données…" - }, - "filters": { - "title": "Inclure uniquement les événements où…", - "empty": "Aucune condition — tous les événements de la plage horaire sont inclus.", - "add": "Ajouter une condition", - "remove": "Retirer", - "field": "Champ", - "fieldPlaceholder": "ex. host.name", - "operator": "Opérateur", - "value": "Valeur", - "valuePlaceholder": "Valeur", - "from": "De", - "to": "À", - "noValue": "Aucune valeur requise", - "listPlaceholder": "Valeurs séparées par des virgules" - }, - "operators": { - "IS": "est", - "IS_NOT": "n'est pas", - "IS_ONE_OF_TERMS": "est l'un de", - "IS_GREATER_THAN": "est supérieur à", - "IS_LESS_THAN_OR_EQUALS": "est inférieur ou égal à", - "IS_BETWEEN": "est entre", - "CONTAIN": "contient", - "DOES_NOT_CONTAIN": "ne contient pas", - "START_WITH": "commence par", - "ENDS_WITH": "se termine par", - "EXIST": "existe", - "DOES_NOT_EXIST": "n'existe pas" - }, - "dimension": { - "title": "Regrouper par", - "field": "Champ", - "placeholder": "Choisissez un champ à regrouper…" - }, - "table": { - "hint": "Affiche tous les champs des enregistrements. Ajoutez des colonnes pour en choisir.", - "columnsTitle": "Colonnes", - "allColumns": "Toutes les colonnes seront affichées. Ajoutez des champs pour en choisir certaines.", - "addColumn": "Ajouter une colonne…", - "removeColumn": "Retirer la colonne" - }, - "chartPreview": { - "title": "Aperçu du graphique", - "noQuery": "Choisissez un jeu de données pour voir un aperçu.", - "error": "La requête d'aperçu a échoué." - }, - "chartTypeChip": { - "label": "Graphique :" - }, - "chartTypeModal": { - "title": "Choisir un type de graphique", - "subtitle": "Choisissez comment visualiser les données. Vous pourrez le modifier plus tard.", - "confirm": "Continuer", - "swapTitle": "Changer le type de graphique", - "swapConfirm": "Appliquer" - }, - "saveVisualization": "Enregistrer le widget", - "fieldSelect": { - "loading": "Chargement des champs…", - "choose": "Choisissez un champ…" - }, - "toast": { - "notReady": "Choisissez un jeu de données et un champ de répartition avant d’enregistrer." - }, - "breakdown": { - "title": "Répartir par", - "topValuesTable": "Tableau des valeurs principales", - "time": "Dans le temps", - "field": "Valeurs les plus fréquentes", - "interval": "Taille de l'intervalle", - "intervalAuto": "Automatique", - "limit": "Combien", - "limitPlaceholder": "Par défaut (50)", - "splitHint": "Facultatif : une ligne par valeur de ce champ." - }, - "editFilters": "Edit filters" - }, - "grid": { - "empty": "Ce tableau de bord ne contient encore aucun widget.", - "missingVisualization": "Widget indisponible", - "unknownVisualization": "Widget" - }, - "widget": { - "renderError": "Impossible d'afficher ce widget.", - "count": "Nombre", - "loading": "Chargement des données…", - "queryError": "Impossible de charger les données du widget.", - "noData": "Aucune donnée pour la plage de temps sélectionnée.", - "regionMapEmpty": "Aucun point avec lat/lon valides.", - "regionMapShapeHint": "Le SQL doit renvoyer des colonnes de latitude et de longitude (ou un tableau value [lat, lon, count]).", - "regionMapUnnamed": "(sans nom)", - "regionMapValue": "valeur : {{value}}", - "editAriaLabel": "Modifier le widget", - "removeAriaLabel": "Retirer le widget", - "moveBack": "Reculer", - "moveForward": "Avancer", - "width": "Largeur", - "height": "Hauteur", - "widthSmall": "1 col", - "widthMedium": "2 cols", - "widthLarge": "3 cols", - "heightNormal": "Normale", - "heightTall": "Haute", - "incompleteSpec": "Il manque une partie de la question de ce widget." - }, - "form": { - "createTitle": "Nouveau tableau de bord", - "renameTitle": "Modifier le tableau de bord", - "name": "Nom", - "namePlaceholder": "ex. Vue d'ensemble du réseau", - "description": "Description", - "descriptionPlaceholder": "Facultatif", - "cancel": "Annuler", - "create": "Créer", - "save": "Enregistrer" - }, - "confirm": { - "deleteTitle": "Supprimer le tableau de bord", - "delete": "Supprimer le tableau de bord « {{name}} » ? Cette action est irréversible.", - "deleteWidgetsTitle": "Supprimer les widgets", - "deleteWidgets_one": "Supprimer ce widget ? Cette action est irréversible.", - "deleteWidgets_other": "Supprimer {{count}} widgets ? Cette action est irréversible.", - "dismissTitle": "Retirer le tableau de bord", - "dismiss": "Supprimer le tableau de bord par défaut « {{name}} » ? Vous pourrez en créer un nouveau à partir de celui-ci avec « Nouveau » → « À partir d'une existante »." - }, - "page": { - "noSelection": "Choisissez un tableau de bord dans la liste ou créez-en un pour commencer.", - "loading": "Chargement des widgets…" }, - "toast": { - "created": "Tableau de bord créé.", - "createFailed": "Impossible de créer le tableau de bord.", - "updated": "Tableau de bord mis à jour.", - "updateFailed": "Impossible de mettre à jour le tableau de bord.", - "deleted": "Tableau de bord supprimé.", - "deleteFailed": "Impossible de supprimer le tableau de bord.", - "layoutSaved": "Disposition enregistrée.", - "layoutSaveFailed": "Impossible d'enregistrer la disposition.", - "visualizationCreated": "Widget créé.", - "visualizationCreateFailed": "Impossible de créer le widget.", - "visualizationUpdated": "Widget mis à jour.", - "visualizationUpdateFailed": "Impossible de mettre à jour le widget.", - "visualizationDeleted": "Widget supprimé.", - "visualizationDeleteFailed": "Impossible de supprimer le widget.", - "filterCreated": "Filtre créé.", - "filterUpdated": "Filtre mis à jour.", - "filterDeleted": "Filtre supprimé.", - "filterCreateFailed": "Echec de la creation du filtre.", - "filterUpdateFailed": "Echec de la mise a jour du filtre.", - "filterDeleteFailed": "Echec de la suppression du filtre.", - "filtersSaved": "Filters saved.", - "filtersSaveFailed": "Could not save filters." - }, - "newDashboard": { - "title": "Nouveau tableau de bord", - "subtitle": "Créez un tableau de bord vide. Vous pourrez ajouter des widgets après l'avoir enregistré.", - "modeManual": "Créer manuellement", - "modeAi": "Avec l'IA", - "aiLocked": "Activez SOC-AI et configurez-le pour utiliser cette fonction.", - "aiDescriptionLabel": "Que doit afficher ce tableau de bord ?", - "aiDescriptionPlaceholder": "ex. Connexions échouées par pays, 7 derniers jours", - "aiCreate": "Créer avec l'IA", - "aiOpenerWithDetails": "Créez un tableau de bord nommé « {{name}} » affichant : {{description}}" - }, - "newVisualization": { - "title": "Nouveau widget", - "subtitle": "Définissez un graphique réutilisable à partir d'une requête SQL et d'une configuration ECharts.", - "sqlQuery": "Requête SQL", - "sqlQueryPlaceholder": "SELECT bucket, count(*) FROM logs GROUP BY bucket", - "sqlQueryHint": "Utilisez les marqueurs timeFilter, from et to (entre doubles accolades) pour appliquer le sélecteur de temps au rendu.", - "config": "Configuration du graphique (option ECharts, JSON)", - "configHint": "Doit être du JSON valide. Les lignes du SQL sont exposées via `dataset.source` — connectez vos séries avec `encode`.", - "configError": "JSON non valide : {{error}}" - }, - "visualizationList": { - "title": "Widgets", - "subtitle": "{{count}} widget(s) disponible(s).", - "subtitleFiltered": "{{shown}} sur {{total}} affichées.", - "create": "Nouvelle", - "searchPlaceholder": "Rechercher des widgets…", - "loading": "Chargement des widgets…", - "empty": "Aucun widget pour le moment.", - "emptyFiltered": "Aucun widget ne correspond aux filtres actuels.", - "delete": "Supprimer", - "deleteTitle": "Supprimer le widget", - "confirmDelete": "Supprimer le widget « {{name}} » ? Cette action est irréversible.", - "filters": { - "search": "Recherche", - "chartType": "Type de graphique", - "allChartTypes": "Tous les types de graphique", - "source": "Source", - "allSources": "Toutes les sources", - "createdAt": "Créée", - "modifiedAt": "Modifiée", - "createdRangeTitle": "Plage personnalisée — Création", - "modifiedRangeTitle": "Plage personnalisée — Modification", - "pickRange": "Choisir une plage", - "datePresets": { - "all": "Toute la période", - "today": "Aujourd'hui", - "last7": "7 derniers jours", - "last30": "30 derniers jours", - "lastYear": "Année dernière", - "custom": "Plage personnalisée" - }, - "clear": "Réinitialiser les filtres" - }, - "col": { - "name": "Nom", - "chartType": "Type de graphique", - "source": "Source", - "description": "Description", - "created": "Créée", - "modified": "Modifiée" - } - }, - "tabs": { - "dashboards": "Tableaux de bord", - "visualizations": "Widgets", - "newDashboard": "Nouveau tableau de bord", - "unsetDefault": "Retirer par défaut", - "options": "Options" - }, - "picker": { - "none": "Sélectionner un tableau de bord", - "search": "Rechercher des tableaux de bord…", - "new": "Nouveau tableau de bord", - "setDefault": "Définir par défaut", - "empty": "Aucun tableau de bord" - }, - "empty": { - "title": "Aucun tableau de bord", - "body": "Créez votre premier tableau de bord pour voir vos données de sécurité d'un coup d'œil.", - "cta": "Créer un tableau de bord" - }, - "filters": { - "addTitle": "Ajouter un filtre", - "editTitle": "Modifier le filtre", - "removeTitle": "Supprimer le filtre", - "removeConfirm": "Supprimer le filtre « {{label}} » ? Cette action est irréversible.", - "remove": "Supprimer", - "editAria": "Modifier le filtre", - "removeAria": "Supprimer le filtre", - "saving": "Enregistrement…", - "addChip": "Ajouter un filtre", - "chooseValue": "Choose…", - "selected": "selected", - "loading": "Loading values…", - "searchPlaceholder": "Search values…", - "noValues": "No values available.", - "loadError": "Could not load values.", - "clear": "Clear", - "editorTitle": "Dashboard filters", - "editorHint": "Add dropdown chips that filter every widget on this dashboard.", - "emptyEditor": "No filter chips yet. Add one to get started.", - "cancel": "Cancel", - "save": "Save", - "field": { - "dataset": "Data set", - "field": "Field", - "chooseField": "Choose a field…", - "label": "Label", - "labelPlaceholder": "e.g. Host", - "placeholder": "Placeholder", - "placeholderPlaceholder": "e.g. Pick a host", - "multiple": "Multiple", - "searchable": "Searchable" - } - }, - "duplicate": { - "copyName": "{{name}} (copie)" - } - }, - "settings": { - "title": "Paramètres", - "license": "Licence", - "notifications": "Notifications", - "connectionKey": "Clé de connexion", - "dataRetention": "Rétention des données", - "indices": "Index", - "theme": "Thème", - "branding": "Marque", - "apiKeys": "Clés API", - "identityProviders": "Fournisseurs d'identité", - "email": "Configuration e-mail", - "dateFormat": "Format de date", - "language": "Langue", - "auditLogs": "Journaux d'audit", - "about": "À propos", - "socAi": "SOC-AI", - "supportAccess": "Accès support", - "threatwinds": "Intégration ThreatWinds" - }, - "topbar": { - "theme": { - "light": "Mode clair", - "dark": "Mode sombre" - }, - "manageLicense": "Gérer la licence", - "profile": { - "profile": "Profil", - "license": "Licence", - "logout": "Se déconnecter" - } - }, - "notifications": { - "title": "Notifications", - "markAllRead": "Tout marquer comme lu", - "empty": "Vous n'avez aucune notification.", - "viewAll": "Voir tout", - "markRead": "Marquer comme lu", - "markUnread": "Marquer comme non lu", - "delete": "Supprimer", - "subtitle": "{{total}} au total · {{unread}} non lues", - "allCaughtUp": "Tout est à jour.", - "loadFailed": "Impossible de charger les notifications." - }, - "pagination": { - "perPage": "Par page", - "pageOf": "Page {{page}} sur {{total}}", - "previous": "Précédent", - "next": "Suivant" - }, - "license": { - "title": "Licence", - "subtitle": "Votre édition, vos fonctionnalités et votre fichier de licence.", - "loading": "Chargement de la licence…", - "loadError": "Impossible de charger les informations de licence.", - "statusLabel": "Statut", - "status": { - "community": "Community", - "active": "Active", - "expiring": "Bientôt expirée", - "expired": "Expirée" - }, - "edition": "Édition", - "enterprise": "Enterprise", - "community": "Community", - "editionLine": "Édition {{edition}}", - "datasourceLimit": "Limite de sources de données", - "unlimited": "Illimité", - "mssp": "MSSP / multi-locataire", - "enabled": "Activé", - "licenseType": "Type de licence", - "instanceId": "ID d'instance", - "enterpriseUnlocked": "Fonctionnalités Enterprise débloquées", - "validUntil": "Valable jusqu'au", - "noExpiry": "Pas d'expiration", - "timeRemaining": "Temps restant", - "expiredAgo": "Expirée il y a {{days}}j", - "daysShort": "{{days}}j", - "msspShort": "MSSP", - "communityEdition": "Édition Community", - "communityBlurb": "Gratuite et open source. Téléchargez une licence Enterprise ci-dessous pour débloquer le multi-locataire, le SSO, des limites de sources de données plus élevées et la conformité avancée.", - "upgrade": "Passer à Enterprise", - "uploadTitle": "Télécharger une licence", - "uploadBlurb": "Installez ou remplacez le fichier LICENSE signé. Le serveur valide la signature et l'expiration avant de l'appliquer. Admin uniquement.", - "installLicense": "Installer la licence", - "chooseFile": "Choisir un fichier", - "noFileSelected": "Aucun fichier sélectionné", - "toast": { - "installed": "Licence installée — édition {{edition}}.", - "adminRequired": "Des privilèges d'administrateur sont requis pour télécharger une licence.", - "invalid": "Fichier de licence invalide ou expiré.", - "installFailed": "Impossible d'installer la licence." - }, - "ingestLimit": "Volume d'ingestion", - "notMetered": "Non mesuré", - "gbPerMonth": "{{gb}} Go/mois" - }, - "audit": { - "title": "Journal d'audit", - "subtitle": "Enregistrement de chaque action pertinente pour la sécurité.", - "totalEntries": "{{total}} entrées au total.", - "loadError": "Impossible de charger le journal d'audit", - "stats": { - "totalEntries": "Total des entrées", - "acrossAllTime": "Sur toute la période", - "successRate": "Taux de réussite", - "failuresOnPage_one": "{{count}} échec sur cette page", - "failuresOnPage_other": "{{count}} échecs sur cette page", - "topAction": "Action principale", - "onPage": "{{count}} sur cette page", - "uniqueActors": "Acteurs uniques", - "includingSystem": "Y compris le système" - }, - "filters": { - "title": "Filtres", - "clear": "Effacer", - "last24h": "Dernières 24h", - "failuresOnly": "Échecs uniquement", - "authEvents": "Événements d'authentification", - "actionPrefix": "Préfixe d'action", - "actionPlaceholder": "ex. auth., user.update", - "status": "Statut", - "any": "Tous", - "resourceType": "Type de ressource", - "resourceTypePlaceholder": "user, alert…", - "resourceId": "ID de ressource", - "user": "Utilisateur", - "userPlaceholder": "login…" - }, - "statusValue": { - "success": "Réussite", - "failure": "Échec" - }, - "table": { - "timestamp": "Horodatage", - "actor": "Acteur", - "action": "Action", - "resource": "Ressource", - "status": "Statut", - "ip": "IP", - "loading": "Chargement…", - "emptyTitle": "Aucune entrée ne correspond à ces filtres.", - "emptyHint": "Essayez d'effacer les filtres ou d'élargir la plage de dates.", - "system": "système", - "view": "Voir" - }, - "drawer": { - "entry": "entrée #{{id}}", - "overview": "Aperçu", - "raw": "JSON brut", - "error": "Erreur", - "actor": "Acteur", - "resource": "Ressource", - "ip": "IP", - "userAgent": "Agent utilisateur", - "session": "Session", - "metadata": "Métadonnées", - "copy": "Copier", - "copied": "Copié", - "copyJson": "Copier le JSON" - } - }, - "team": { - "title": "Équipe", - "subtitle": "Gérez les utilisateurs et leurs rôles.", - "tabs": { - "members": "Membres", - "roles": "Rôles et permissions" - }, - "toast": { - "rolesLoadFailed": "Impossible de charger les rôles", - "userLoadFailed": "Impossible de charger l'utilisateur", - "rolesUpdated": "Rôles mis à jour", - "userReactivated": "Utilisateur réactivé", - "userDeactivated": "Utilisateur désactivé", - "tfaReset": "Authentification à deux facteurs réinitialisée", - "invitationSent": "Invitation envoyée", - "loginOrEmailInUse": "Cet identifiant ou cet e-mail est déjà utilisé", - "invalidRequest": "Requête invalide", - "noPermission": "Vous n'avez pas la permission de faire cela", - "userNotFound": "Utilisateur introuvable", - "operationFailed": "L'opération a échoué", - "emailInUse": "Cet e-mail est déjà utilisé", - "roleCreated": "Rôle créé", - "roleUpdated": "Rôle mis à jour", - "roleDeleted": "Rôle supprimé", - "roleNameInUse": "Un rôle avec cet identifiant existe déjà", - "roleImmutable": "Les rôles système ne peuvent pas être modifiés", - "permissionsLoadFailed": "Impossible de charger les permissions", - "localUserCreated": "Utilisateur local créé" - }, - "members": { - "searchPlaceholder": "Rechercher par nom ou e-mail…", - "invite": "Inviter un utilisateur", - "colUser": "Utilisateur", - "colRoles": "Rôles", - "col2fa": "2FA", - "colStatus": "Statut", - "loading": "Chargement des utilisateurs…", - "loadFailed": "Impossible de charger les utilisateurs.", - "retry": "Réessayer", - "noSearchMatch": "Aucun utilisateur ne correspond à votre recherche.", - "none": "Aucun utilisateur pour le moment.", - "noRole": "aucun", - "on": "Oui", - "off": "Non", - "countLabel_one": "{{count}} utilisateur · page {{page}} sur {{pages}}", - "countLabel_other": "{{count}} utilisateurs · page {{page}} sur {{pages}}", - "federated": "SSO" - }, - "status": { - "inactive": "Inactif", - "pendingPassword": "Mot de passe en attente", - "active": "Actif", - "pending": "Invitation en attente", - "suspended": "Suspendu" - }, - "drawer": { - "createdBy": "créé par {{actor}}", - "loading": "Chargement…", - "profileTitle": "Profil", - "profileSubtitle": "Seul l'utilisateur peut modifier ces informations, depuis son propre profil.", - "name": "Nom", - "username": "Identifiant", - "email": "E-mail", - "language": "Langue", - "accountTitle": "Compte", - "status": "Statut", - "statusActive": "Actif", - "statusInactive": "Inactif", - "tfa": "2FA", - "tfaEnabled": "Activée", - "tfaNotConfigured": "Non configuré", - "resetTfa": "Réinitialiser", - "resetTfaHint": "Désactive la 2FA de cet utilisateur pour qu'il la reconfigure à la prochaine connexion", - "resetTfaConfirmTitle": "Réinitialiser l'authentification à deux facteurs ?", - "resetTfaConfirmBody": "Cela désactive la 2FA de {{name}}. Il se connectera uniquement avec son mot de passe et pourra la reconfigurer depuis son profil.", - "resetTfaConfirm": "Réinitialiser la 2FA", - "pendingPasswordNote": "Utilise encore le mot de passe temporaire (invitation non terminée).", - "lastModified": "Modifié {{time}}", - "rolesTitle": "Rôles", - "rolesSubtitle": "Les rôles accordent des permissions de module. Un utilisateur peut en avoir plusieurs.", - "noRoleWarning": "Aucun rôle attribué — l'utilisateur n'aura accès à aucun module.", - "deactivate": "Désactiver", - "reactivate": "Réactiver", - "waitingInvite": "En attente de l'acceptation de l'invitation par l'utilisateur.", - "cancel": "Annuler", - "saving": "Enregistrement…", - "saveRoles": "Enregistrer les rôles", - "created": "créé {{time}}", - "pendingNote": "L'invitation n'a pas encore été acceptée.", - "federatedNote": "Se connecte via un fournisseur d'identité." - }, - "invite": { - "title": "Inviter un utilisateur", - "description": "Le compte est créé inactif. La personne reçoit un e-mail pour définir son mot de passe et l'activer.", - "username": "Identifiant", - "usernameHint": "Au moins 3 caractères.", - "email": "E-mail", - "firstName": "Prénom", - "lastName": "Nom", - "roles": "Rôles", - "cancel": "Annuler", - "sending": "Envoi…", - "send": "Envoyer l'invitation", - "name": "Nom", - "emailHint": "C'est l'adresse utilisée pour se connecter.", - "localDescription": "Le compte est créé avec un mot de passe et activé immédiatement. Aucun e-mail n'est envoyé.", - "modeInvite": "Inviter un utilisateur", - "modeLocal": "Créer un utilisateur local", - "passwordLabel": "Mot de passe", - "passwordPlaceholder": "Définir un mot de passe robuste", - "localUserNote": "Cet utilisateur ne recevra pas d'e-mail et sera activé automatiquement.", - "createLocal": "Créer l'utilisateur", - "passwordRules": { - "length": "Au moins 8 caractères", - "case": "Au moins une majuscule et une minuscule", - "special": "Au moins un caractère spécial" - }, - "emailInvalid": "Veuillez saisir une adresse e-mail valide" - }, - "rolePicker": { - "none": "Aucun rôle disponible." - }, - "roles": { - "loading": "Chargement des rôles…", - "loadFailed": "Impossible de charger les permissions des rôles.", - "readonlyNote": "Les rôles et leurs permissions sont définis par le système et en lecture seule. Attribuez-les aux utilisateurs depuis l'onglet Membres.", - "permissionsCount_one": "{{count}} permission", - "permissionsCount_other": "{{count}} permissions", - "modulesCount_one": "{{count}} module", - "modulesCount_other": "{{count}} modules", - "matrixTitle": "Matrice des permissions", - "matrixSubtitle": "Ce que chaque rôle peut faire, par module.", - "permission": "Permission", - "systemNote": "Les rôles système sont fournis avec la plateforme et ne sont pas modifiables. Ceux que vous créez appartiennent à ce locataire.", - "newRole": "Nouveau rôle", - "edit": "Modifier", - "delete": "Supprimer", - "systemBadge": "Système", - "createTitle": "Nouveau rôle", - "editTitle": "Modifier le rôle", - "editorSubtitle": "Choisissez ce que ce rôle peut faire. Une personne peut en cumuler plusieurs.", - "nameLabel": "Identifiant", - "nameHint": "Utilisé dans le code et l'API. Par exemple ROLE_AUDITOR.", - "displayNameLabel": "Nom affiché", - "descriptionLabel": "Description", - "permissionsLabel": "Permissions", - "selectedCount": "{{count}} sélectionnées", - "toggleAll": "toutes", - "loadingPermissions": "Chargement des permissions…", - "save": "Enregistrer le rôle", - "deleteConfirmTitle": "Supprimer ce rôle ?", - "deleteConfirmBody": "{{name}} sera supprimé. Les personnes qui n'ont que ce rôle perdront l'accès aux modules." - }, - "langDefault": "Par défaut du système", - "relative": { - "justNow": "à l'instant", - "minutesAgo": "il y a {{count}} min", - "hoursAgo": "il y a {{count}} h", - "daysAgo": "il y a {{count}} j" - }, - "roleNames": { - "ROLE_ADMIN": "Administrateur", - "ROLE_USER": "Utilisateur" - }, - "roleDescriptions": { - "ROLE_ADMIN": "Accès complet à toutes les ressources", - "ROLE_USER": "Utilisateur standard avec accès en lecture au niveau des modules" - }, - "actions": { - "read": "Lecture", - "write": "Écriture", - "delete": "Suppression" - }, - "resources": { - "adaudit": "Audit AD", - "alerts": "Alertes", - "audit": "Journal d'audit", - "compliance": "Conformité", - "config": "Configuration", - "dashboards": "Tableaux de bord", - "datasources": "Datasources", - "eventprocessing": "Traitement des événements", - "idp": "Fournisseurs d'identité", - "incidents": "Incidents", - "integrations": "Intégrations", - "loganalyzer": "Analyseur de logs", - "opensearch": "OpenSearch", - "roles": "Rôles", - "soar": "SOAR", - "users": "Utilisateurs", - "notifications": "Notifications", - "socai": "SOC AI", - "tenant": "Locataires", - "threatintel": "Renseignement sur les menaces" - } - }, - "apiKeys": { - "title": "Clés API", - "subtitle": "Jetons d’accès programmatique pour l’API UTMStack.", - "new": "Nouvelle clé API", - "searchPlaceholder": "Rechercher par nom ou IP autorisée…", - "refresh": "Actualiser", - "loading": "Chargement des clés API…", - "loadFailed": "Impossible de charger les clés API.", - "retry": "Réessayer", - "noSearchMatch": "Aucune clé API ne correspond à votre recherche.", - "empty": "Aucune clé API pour l’instant. Créez-en une pour commencer.", - "anyIp": "Toute IP", - "never": "Jamais", - "count_one": "{{count}} clé · page {{page}} sur {{pages}}", - "count_other": "{{count}} clés · page {{page}} sur {{pages}}", - "enterprise": { - "title": "Les clés API sont une fonctionnalité Enterprise", - "body": "Émettez, restreignez et faites tourner des clés API pour l’accès programmatique à l’API UTMStack. Cette fonctionnalité est disponible dans l’édition Enterprise.", - "upgrade": "Passer à Enterprise", - "manageLicense": "Gérer votre licence" - }, - "col": { - "name": "Nom", - "allowedIps": "IP autorisées", - "created": "Créée", - "lastRotated": "Dernière rotation", - "expires": "Expire", - "status": "Statut", - "actions": "Actions" - }, - "status": { - "active": "Active", - "expiring": "Bientôt expirée", - "expired": "Expirée" - }, - "action": { - "rotate": "Faire tourner", - "edit": "Modifier", - "delete": "Supprimer" - }, - "dialog": { - "editTitle": "Modifier la clé API", - "newTitle": "Nouvelle clé API", - "name": "Nom", - "namePlaceholder": "ci-pipeline", - "allowedIps": "IP autorisées", - "allowedIpsHint": "Séparées par des virgules. Laissez vide pour autoriser toute IP.", - "expires": "Expire", - "expiresHint": "Laissez vide pour une clé qui n’expire jamais.", - "secretNote": "Le jeton secret est affiché une seule fois, juste après la création. Copiez-le alors — il ne peut pas être récupéré ensuite (seulement renouvelé).", - "cancel": "Annuler", - "saving": "Enregistrement…", - "saveChanges": "Enregistrer les modifications", - "createKey": "Créer la clé" - }, - "confirm": { - "deleteTitle": "Supprimer la clé API", - "rotateTitle": "Faire tourner la clé API", - "deleteBody": "Supprimer {{name}} ? Tout client qui l’utilise perdra immédiatement l’accès. Cette action est irréversible.", - "rotateBody": "Faire tourner {{name}} ? Un nouveau secret est émis et l’actuel cesse de fonctionner immédiatement. Le nouveau jeton est affiché une seule fois.", - "cancel": "Annuler", - "working": "En cours…", - "delete": "Supprimer", - "rotate": "Faire tourner" - }, - "reveal": { - "title": "Clé API créée", - "note": "Copiez ce secret maintenant — pour {{name}}. Il ne sera plus affiché. Si vous le perdez, faites tourner la clé.", - "copied": "Copié", - "copy": "Copier", - "done": "Terminé" - }, - "toast": { - "updated": "Clé API mise à jour", - "secretIssueFailed": "Clé créée, mais le secret n’a pas pu être émis. Utilisez Faire tourner pour en obtenir un.", - "deleted": "Clé API supprimée" - }, - "error": { - "nameTaken": "Une clé API portant ce nom existe déjà", - "enterpriseRequired": "Les clés API nécessitent l’édition Enterprise", - "notFound": "Clé API introuvable", - "invalidRequest": "Requête invalide", - "failed": "Échec de l’opération" - } - }, - "idp": { - "title": "Fournisseurs d'identité", - "subtitle": "Authentification unique SAML 2.0 pour votre organisation.", - "add": "Ajouter un fournisseur", - "enterprise": { - "title": "Le SSO est une fonctionnalité Enterprise", - "body": "Connectez un fournisseur d'identité SAML 2.0 (Entra ID, Okta, Google Workspace…) pour que votre équipe se connecte avec votre IdP. L'authentification unique est disponible dans l'édition Enterprise.", - "upgrade": "Passer à Enterprise" - }, - "loading": "Chargement des fournisseurs d'identité…", - "loadFailed": "Impossible de charger les fournisseurs d'identité.", - "retry": "Réessayer", - "empty": { - "title": "Aucun fournisseur d'identité configuré", - "body": "Ajoutez un fournisseur SAML 2.0 pour que votre équipe se connecte avec votre IdP d'entreprise." - }, - "card": { - "enable": "Activer", - "disable": "Désactiver", - "active": "Actif", - "disabled": "Désactivé", - "metadataUrl": "URL des métadonnées", - "spEntityId": "SP Entity ID", - "spAcsUrl": "SP ACS URL", - "loginUrl": "URL de connexion", - "copy": "Copier", - "edit": "Modifier", - "delete": "Supprimer", - "jit": "Provisioning", - "jitOn": "creates accounts on first sign-in", - "sync": "Roles", - "syncOn": "re-applied on every sign-in" - }, - "form": { - "addTitle": "Ajouter un fournisseur d'identité", - "editTitle": "Modifier le fournisseur d'identité", - "name": "Nom", - "nameHint": "Unique. Utilisé dans l'URL SSO.", - "providerType": "Type de fournisseur", - "providerTypeHint": "Une étiquette, p. ex. azure, okta, google.", - "metadataUrl": "URL des métadonnées de l'IdP", - "spEntityId": "SP Entity ID", - "spAcsUrl": "SP ACS URL", - "certificate": "Certificat SP (PEM)", - "privateKey": "Clé privée SP (PEM)", - "privateKeyHintEdit": "Laissez vide pour conserver la clé enregistrée.", - "privateKeyHintCreate": "Requise. Stockée chiffrée ; jamais affichée à nouveau.", - "privateKeyUnchanged": "•••••••• (inchangée)", - "active": "Actif (afficher sur la page de connexion)", - "cancel": "Annuler", - "saving": "Enregistrement…", - "save": "Enregistrer les modifications", - "create": "Créer le fournisseur", - "issuer": "Issuer URL", - "issuerHint": "Discovery runs against this; the provider must serve /.well-known/openid-configuration under it.", - "clientId": "Client ID", - "redirectUrl": "Redirect URL", - "redirectUrlHint": "Register this exact URL with the provider.", - "host": "Host", - "port": "Port", - "startTls": "TLS", - "startTlsOn": "Use StartTLS", - "bindDn": "Bind DN", - "bindDnHint": "A service account that may search the directory.", - "baseDn": "Base DN", - "userFilter": "User filter", - "userFilterHint": "Must contain %s, where the address typed at login is placed.", - "emailAttribute": "Email attribute", - "nameAttribute": "Name attribute", - "groupAttribute": "Group attribute", - "provisioning": "Accounts and roles", - "provisioningHint": "What happens when someone the directory vouches for signs in.", - "jit": "Create the account on first sign-in", - "defaultRole": "Default role", - "defaultRoleHint": "Given when no group matches. Without one, an unmatched sign-in is refused.", - "noDefaultRole": "None", - "groupsAttribute": "Groups attribute", - "groupsAttributeHint": "Where the provider puts group membership.", - "syncRoles": "Re-apply roles on every sign-in", - "syncRolesHint": "Roles not in the mapping are removed, so a change in the directory reaches here. Without this, a demotion never arrives.", - "mappings": "Group to role", - "mappingsHint": "A directory group on the left, the role it grants on the right.", - "addMapping": "Add", - "noMappings": "No mappings. Everyone gets the default role.", - "groupPlaceholder": "SOC Analysts", - "pickRole": "Pick a role", - "secret.saml": "SP private key", - "secret.oidc": "Client secret", - "secret.ldap": "Bind password", - "secretHintCreate": "Stored encrypted and never shown again.", - "secretHintEdit": "Leave blank to keep the stored one.", - "secretUnchanged": "inchangé", - "errors": { - "required": "Ce champ est obligatoire.", - "url": "Doit être une URL http(s) valide.", - "httpsUrl": "Doit être une URL https valide.", - "hostname": "Saisissez un hôte ou une IP sans schéma (ex. ldap.exemple.fr).", - "port": "Le port doit être un nombre entier entre 0 et 65535.", - "pemCertificate": "Ne ressemble pas à un certificat PEM (-----BEGIN/END CERTIFICATE----- manquant).", - "pemKey": "Ne ressemble pas à une clé privée PEM (-----BEGIN/END PRIVATE KEY----- manquant).", - "userFilterPlaceholder": "Le filtre doit contenir %s, là où est placée l'adresse de connexion.", - "userFilterUnbalanced": "Parenthèses déséquilibrées — la recherche ne renverra rien.", - "nameFormat": "Utilisez lettres, chiffres, points, tirets ou tirets bas (64 max). Il apparaît dans l'URL SSO, sans espaces.", - "redirectUrl": "Doit être une URL https valide, ou une URL http de loopback (localhost / 127.0.0.1 / [::1]).", - "entityId": "Doit être une URI valide, ex. https://utmstack.example.com/sp." - } - }, - "delete": { - "title": "Supprimer le fournisseur d'identité", - "body": "Supprimer {{name}} ? Les utilisateurs ne pourront plus se connecter via celui-ci. Cette action est irréversible.", - "cancel": "Annuler", - "deleting": "Suppression…", - "confirm": "Supprimer" - }, - "toast": { - "enabled": "Fournisseur activé", - "disabled": "Fournisseur désactivé", - "created": "Fournisseur d'identité créé", - "updated": "Fournisseur d'identité mis à jour", - "deleted": "Fournisseur d'identité supprimé", - "paidPlan": "Le SSO SAML nécessite un forfait payant", - "enterpriseRequired": "Le SSO nécessite l'édition Enterprise", - "notFound": "Fournisseur d'identité introuvable", - "invalid": "Configuration invalide", - "failed": "L'opération a échoué" - }, - "providerType": { - "saml": "SAML 2.0", - "oidc": "OpenID Connect", - "ldap": "LDAP / Active Directory", - "comingSoon": "pas encore disponible" - } - }, - "userAuditor": { - "title": "Auditeur d’utilisateurs", - "subtitle": "Comptes Active Directory observés dans vos journaux de sécurité Windows — découverts à partir d’événements de création, de connexion et de suppression.", - "export": "Exporter", - "accountsChip": "{{count}} comptes", - "overview": { - "title": "Inventaire des comptes", - "active": "actifs", - "disabled": "désactivés", - "deleted": "supprimés", - "seen24h": "{{count}} vus au cours des dernières 24 heures", - "byDomain": "Par domaine" - }, - "views": { - "all": "Tous les comptes", - "windows": "Windows", - "linux": "Linux", - "active": "Actifs", - "disabled": "Désactivés", - "deleted": "Supprimés", - "service": "Comptes de service", - "stale": "Inactifs (30j+)" - }, - "searchPlaceholder": "Rechercher par nom de compte ou SID…", - "allTenants": "Tous les locataires", - "filters": { - "add": "Ajouter un filtre", - "clearAll": "Tout effacer", - "filterValues": "Filtrer les valeurs…", - "loadingValues": "Chargement des valeurs…", - "noValues": "Aucune valeur trouvée.", - "pickValue": "Choisissez une valeur pour ajouter le filtre.", - "empty": "(vide)", - "cancel": "Annuler", - "addBtn": "Ajouter" - }, - "filterFields": { - "status": "Statut du cycle de vie" - }, - "ops": { - "is": "est" - }, - "refresh": "Actualiser", - "layout": { - "list": "Liste", - "cards": "Cartes" - }, - "list": { - "account": "Compte", - "identity": "Identité", - "sid": "SID", - "status": "Statut", - "lastLogon": "Dernière connexion", - "lastSeen": "Vu pour la dernière fois", - "tenant": "Locataire" - }, - "status": { - "active": "Actif", - "disabled": "Désactivé", - "deleted": "Supprimé" - }, - "badge": { - "service": "service", - "stale": "inactif" - }, - "empty": "Aucun compte ne correspond à cette vue.", - "loadError": "Impossible de charger les comptes AD.", - "retry": "Réessayer", - "card": { - "lastLogon": "Dernière connexion" - }, - "pageInfo": "{{from}}–{{to}} sur {{count}}", - "drawer": { - "tenantInline": "locataire {{id}}", - "serviceAccount": "compte de service", - "stale": "inactif 30j+", - "viewInLogs": "Voir les événements dans le Log Explorer", - "copySid": "Copier le SID", - "copyUid": "Copier l’identité", - "copied": "Copié", - "identity": "Identité", - "accountName": "Nom du compte", - "domain": "Domaine", - "hostname": "Nom d’hôte", - "sid": "SID", - "uidNumber": "UID", - "machineId": "ID de machine", - "tenant": "Locataire", - "adStatus": "Statut AD", - "enabled": "Activé", - "disabled": "Désactivé", - "lifecycle": "Cycle de vie", - "created": "Compte créé", - "lastLogon": "Dernière connexion", - "lastSeen": "Vu pour la dernière fois dans les journaux", - "deleted": "Compte supprimé", - "noLifecycle": "Aucun événement de cycle de vie enregistré." - }, - "relative": { - "justNow": "à l’instant", - "minutesAgo": "il y a {{count}}m", - "hoursAgo": "il y a {{count}}h", - "daysAgo": "il y a {{count}}j" - }, - "none": "—" - }, - "connectionKey": { - "title": "Clé de connexion", - "subtitle1": "La clé que les agents présentent lors de leur enregistrement sur cette instance.", - "subtitleEmphasis": "Elle sert uniquement à l'installation des agents", - "subtitle2": "— pas pour les collecteurs, les intégrations ou l'API. Elle est gérée par l'agent-manager.", - "status": { - "label": "Statut", - "loading": "Chargement…", - "unavailable": "Agent-manager indisponible", - "active": "Active", - "unavailableHint": "Impossible de contacter l'agent-manager pour lire la clé.", - "activeHint": "Les agents peuvent s'enregistrer avec cette clé." - }, - "token": { - "title": "Clé de connexion", - "subtitle": "Traitez cette valeur comme un identifiant. La faire tourner émet une nouvelle clé pour les futures installations d'agents — les agents déjà enregistrés continuent de fonctionner.", - "loadFailedTitle": "Impossible de charger la clé de connexion", - "unavailableTitle": "Clé de connexion indisponible", - "loadFailedHint": "La clé est gérée par l'agent-manager, qui n'a pas répondu. Réessayez dans un instant.", - "retry": "Réessayer", - "show": "Afficher la clé", - "hide": "Masquer la clé", - "copy": "Copier", - "copied": "Copié", - "regenerate": "Régénérer la clé de connexion", - "confirmTitle": "Régénérer la clé ?", - "confirmBody": "Les nouvelles installations d'agents auront besoin de la nouvelle clé. Les agents déjà enregistrés continuent de fonctionner. Action irréversible.", - "regenerating": "Régénération…", - "confirmYes": "Oui, régénérer", - "cancel": "Annuler" - }, - "security": { - "title": "Recommandations de sécurité", - "subtitle": "Bonnes pratiques pour protéger cet identifiant.", - "rotateTitle": "Renouveler tous les 90 jours", - "rotateBody": "Planifiez une rotation récurrente. UTMStack peut vous envoyer un rappel par e-mail lorsque la clé a plus de 90 jours.", - "rotateAction": "Configurer un rappel", - "secretTitle": "Stockez-la comme un secret", - "secretBody": "Ne la committez pas dans le contrôle de version. Utilisez votre gestionnaire de secrets (Vault, AWS SM, etc.) et injectez-la au moment de l'installation.", - "auditTitle": "Auditez qui l'a récupérée", - "auditBody": "Chaque récupération et rotation est enregistrée dans le journal d'audit de l'application.", - "auditAction": "Voir le journal d'audit" - }, - "toast": { - "loadFailed": "Impossible de charger la clé de connexion", - "rotated": "Clé de connexion renouvelée", - "rotateFailed": "Impossible de renouveler la clé de connexion", - "copyFailed": "Impossible de copier" - } - }, - "dataRetention": { - "title": "Rétention des données", - "subtitle": "How long each dataset is kept, and when its records stop costing local disk.", - "loading": "Chargement…", - "loadFailed": "Could not read the store.", - "retry": "Réessayer", - "datasets": { - "logs": "Logs", - "alerts": "Alerts", - "statistics": "Ingestion statistics" - }, - "holding": "{{documents}} records · {{size}}", - "since": "since {{date}}", - "diskUsed": "Disk {{pct}}% used", - "keep": "Delete after", - "keepHint": "A record is deleted this many days after it happened, wherever it is stored by then.", - "cold": "Move to cold storage after", - "coldHint": "Older records move to object storage and stay queryable. 0 keeps everything on local disk.", - "coldUnavailable": "Set up cold storage below to move older records off local disk.", - "coldBeforeDelete": "Records have to move before they are deleted: use fewer days than the lifetime, or 0.", - "tieredNote": "This dataset moves records to cold storage. Going back to local-only needs the table rebuilt, so it cannot be turned off here.", - "days": "jours", - "save": "Enregistrer", - "saving": "Enregistrement…", - "toast": { - "saved": "Retention saved", - "noPermission": "You do not have permission to change retention", - "saveFailed": "Could not save the retention" - }, - "coldStorage": { - "title": "Cold storage", - "hint": "An object store the event store treats as a second, slower disk. Older records move there and are still queried from the same place — it is not an archive and nothing has to be restored.", - "active": "In use", - "inactive": "Not set up", - "writtenNotReady": "The bucket is configured but the store has not picked it up. Check that the deployment shares the store's configuration directory.", - "endpoint": "Bucket URL", - "accessKey": "Access key", - "secretKey": "Secret key", - "bucketLocked": "The credentials can be changed at any time. The bucket cannot, once records live in it: the parts already moved carry it.", - "enable": "Enable cold storage", - "update": "Update credentials", - "toast": { - "saved": "Cold storage configured", - "failed": "Could not configure cold storage" - }, - "kind": "Type", - "kind_s3": "Stockage objet compatible S3", - "kind_local": "Dossier local ou NFS", - "kind_azure": "Azure Blob Storage", - "accountUrl": "URL du compte de stockage", - "container": "Conteneur", - "accountName": "Nom du compte", - "accountKey": "Clé du compte", - "useRole": "Utiliser le rôle IAM du serveur au lieu de clés", - "s3Hint": "Fonctionne avec AWS S3 et tout stockage compatible S3 : MinIO, Ceph, Wasabi, Cloudflare R2 ou Google Cloud Storage (endpoint https://storage.googleapis.com// avec clés HMAC).", - "localHint": "Les enregistrements passent dans le dossier monté sur /mnt/utmstack-cold dans le magasin d'événements : un répertoire ordinaire du dossier de données, ou un partage NFS monté sur l'hôte sur /clickhouse/cold avant le démarrage du stack. Aucun identifiant requis.", - "changeWarning": "Records already moved to the current destination are not migrated. They stay there and stop being readable from here until the old destination is copied across by hand." - }, - "forbidden": { - "title": "Cette page appartient à la plateforme", - "body": "La rétention s'applique aux tables partagées par tous les locataires : seul un administrateur de la plateforme peut la lire ou la modifier." - } - }, - "languageSettings": { - "title": "Langue de la plateforme", - "subtitle": "Langue d'interface par défaut pour les écrans de pré-connexion, les e-mails système et les nouveaux utilisateurs. Chaque utilisateur peut choisir la sienne dans son profil.", - "label": "Langue par défaut", - "hint": "Utilisée lorsqu'un utilisateur n'a pas choisi sa propre langue.", - "save": "Enregistrer", - "saving": "Enregistrement…", - "saved": "Langue de la plateforme mise à jour", - "loadError": "Impossible de charger le paramètre de langue", - "saveError": "Impossible d'enregistrer le paramètre de langue" - }, - "branding": { - "title": "Marque", - "subtitle": "Personnalisez UTMStack avec l’identité de votre organisation — appliquée partout : écran de connexion, barre latérale, e-mails et rapports.", - "enterpriseRequired": "Le white-label est une fonctionnalité Enterprise.", - "manageLicense": "Gérer la licence", - "enable": { - "title": "White-label", - "description": "Remplacez la marque UTMStack par la vôtre sur toute la plateforme.", - "label": "Activer le white-label" - }, - "identity": { - "title": "Identité", - "productName": "Nom du produit", - "productNameHint": "Affiché dans la barre de titre, la barre latérale et les e-mails.", - "accent": "Couleur d’accent", - "accentHint": "Couleur principale des boutons, liens et états actifs.", - "custom": "Couleur personnalisée" - }, - "logos": { - "title": "Logos", - "hint": "PNG, SVG, WEBP, JPG ou ICO. Jusqu’à 5 Mo.", - "logo": "Logo (clair)", - "logoDark": "Logo (sombre)", - "favicon": "Favicon" - }, - "reports": { - "title": "Ressources de rapport", - "hint": "Intégrées dans les rapports PDF générés.", - "reportLogo": "Logo du rapport", - "reportCover": "Couverture du rapport" - }, - "asset": { - "upload": "Téléverser", - "replace": "Remplacer" - }, - "save": "Enregistrer les modifications", - "saving": "Enregistrement…", - "saved": "Marque mise à jour", - "saveError": "Impossible d’enregistrer la marque", - "uploaded": "Image téléversée", - "uploadError": "Impossible de téléverser l’image", - "loadError": "Impossible de charger la marque", - "enterprise": { - "title": "La marque blanche est une fonctionnalité Enterprise", - "body": "Remplacez le nom du produit, le logo et la couverture des rapports par les vôtres, afin que la console et tout ce qu'elle génère portent votre marque plutôt que celle d'UTMStack.", - "upgrade": "Passer à Enterprise" - }, - "restore": "Rétablir les valeurs UTMStack", - "restored": "Marque rétablie aux valeurs UTMStack" - }, - "emailConfig": { - "title": "Configuration e-mail", - "subtitle": "Serveur SMTP utilisé pour envoyer les notifications d’alertes, les rapports et les e-mails de compte.", - "server": { - "title": "Serveur SMTP", - "host": "Hôte", - "hostHint": "Nom d’hôte de votre serveur SMTP.", - "port": "Port", - "encryption": "Chiffrement", - "username": "Nom d’utilisateur", - "password": "Mot de passe", - "passwordSetHint": "Un mot de passe est enregistré. Laissez vide pour le conserver, ou saisissez-en un nouveau pour le modifier." - }, - "encryptionOpt": { - "TLS": "TLS", - "SSL": "SSL", - "NONE": "Aucun" - }, - "sender": { - "title": "Expéditeur", - "from": "Adresse d’expéditeur", - "fromHint": "Adresse depuis laquelle les e-mails sont envoyés.", - "organization": "Nom de l’organisation", - "organizationHint": "Affiché dans les e-mails de notification d’alertes et d’incidents.", - "baseUrl": "URL de base", - "baseUrlHint": "URL publique de cette instance, utilisée pour les liens dans les e-mails." - }, - "test": { - "button": "Envoyer un test", - "sending": "Envoi…", - "sentTo": "Un e-mail de test sera envoyé à {{email}}.", - "success": "E-mail de test envoyé à {{email}}", - "fail": "Impossible d’envoyer l’e-mail de test", - "fromRequired": "Définissez une adresse d’expéditeur avant de tester" - }, - "save": "Enregistrer les modifications", - "saving": "Enregistrement…", - "saved": "Configuration e-mail enregistrée", - "saveError": "Impossible d’enregistrer la configuration", - "loadError": "Impossible de charger la configuration", - "recipients": { - "alertsTitle": "Destinataires des alertes", - "incidentsTitle": "Destinataires des incidents", - "to": "À", - "cc": "Cc", - "alertsHelper": "Adresses prévenues lors de nouvelles alertes. Laissez vide et les alertes ne sont pas envoyées par e-mail.", - "incidentsHelper": "Adresses prévenues à la création d'un incident. Laissez vide et les incidents ne sont pas envoyés par e-mail.", - "add": "Ajouter" - } - }, - "dateFormat": { - "title": "Date et heure", - "subtitle": "Comment les horodatages sont affichés sur la plateforme. Les journaux sont toujours stockés en UTC.", - "timezone": { - "title": "Fuseau horaire", - "hint": "Les horodatages sont affichés dans ce fuseau horaire. Les données stockées restent en UTC.", - "system": "Par défaut du navigateur", - "now": "Maintenant : {{value}}" - }, - "format": { - "title": "Format de date", - "hint": "Style utilisé pour les dates et heures." - }, - "styles": { - "short": "Court", - "medium": "Moyen", - "long": "Long", - "full": "Complet" - }, - "save": "Enregistrer les modifications", - "saving": "Enregistrement…", - "saved": "Paramètres de date enregistrés", - "saveError": "Impossible d’enregistrer les paramètres", - "loadError": "Impossible de charger les paramètres" - }, - "about": { - "title": "À propos de cette instance", - "subtitle": "Version, licence et état du système de ce déploiement UTMStack.", - "loading": "Chargement des informations de l'instance…", - "edition": { - "enterprise": "Enterprise", - "community": "Community" - }, - "fields": { - "hostname": "Serveur", - "instanceId": "ID d'instance", - "noInstanceMeta": "Aucune métadonnée d'instance disponible." - }, - "license": { - "title": "Licence", - "enterpriseMssp": "Enterprise · MSSP", - "datasources": "Datasources", - "communityLimited": "Limite Community", - "unlimited": "Illimité", - "expires": "Expire", - "managedNote": "L'édition, les limites de datasources et l'upload de licence sont gérés sur la page Licence.", - "view": "Voir la licence", - "ingest": "Volume d'ingestion", - "notMetered": "Non mesuré", - "gbPerMonth": "{{gb}} Go/mois" - }, - "services": { - "backend": { - "name": "Backend API", - "desc": "Passerelle REST, authentification et orchestration des modules." - }, - "opensearch": { - "name": "OpenSearch", - "desc": "Stockage des logs et événements.", - "detail": "{{nodes}} nœuds · {{shards}} shards" - }, - "unreachable": "Inaccessible" - }, - "status": { - "up": "Sain", - "degraded": "Dégradé", - "down": "Hors service", - "unknown": "Inconnu" - }, - "health": { - "title": "État du système", - "allHealthy": "Tous les services sont sains. Actualisez pour revérifier.", - "issues_one": "{{count}} service nécessite une attention.", - "issues_other": "{{count}} services nécessitent une attention.", - "refresh": "Actualiser" - }, - "usage": { - "title": "Sources de données", - "subtitle": "Sources de données configurées dans ce déploiement.", - "ofUnlimited": "sur illimité", - "ofLimit": "sur {{limit}}", - "overLimit": "Au-delà de la limite sous licence — les données au-delà du plafond sont à risque.", - "configured": "configurées" - }, - "support": { - "title": "Support", - "docs": "Documentation", - "repo": "Dépôt GitHub", - "issues": "Signaler un problème", - "website": "utmstack.com" - }, - "legal": { - "title": "Mentions légales", - "license": "Licence", - "security": "Divulgation de sécurité", - "copyright": "© {{year}} UTMStack. Tous droits réservés." - } - }, - "logExplorer": { - "title": "Explorateur de logs", - "eventsIn": "événements dans", - "searching": "Recherche…", - "query": { - "allDataTypes": "Tous les types de données", - "dataTypes": "Types de données", - "exportCsv": "Exporter CSV", - "filterDataTypes": "Filtrer les types de données…", - "noDataTypes": "Aucun type de données", - "noDataTypesMatch": "Aucun type de données correspondant", - "noTextSearch": "Cette source n’a pas de champ plein texte — filtrez par champ", - "refresh": "Actualiser", - "run": "Exécuter", - "search": "Rechercher", - "searchPlaceholder": "Rechercher dans tous les champs…" - }, - "time": { - "15m": "15 dernières minutes", - "1h": "Dernière heure", - "6h": "6 dernières heures", - "24h": "24 dernières heures", - "7d": "7 derniers jours", - "30d": "30 derniers jours" - }, - "ops": { - "is": "est", - "isNot": "n'est pas", - "contains": "contient", - "exists": "existe", - "between": "entre", - "search": "recherche", - "isOneOf": "est parmi", - "isNotOneOf": "n'est aucun de", - "doesNotContain": "no contiene", - "startsWith": "empieza con", - "doesNotStartWith": "no empieza con", - "endsWith": "termina con", - "doesNotEndWith": "no termina con", - "doesNotExist": "no existe", - "notBetween": "no está entre", - "greaterThan": "es mayor que", - "greaterThanOrEquals": "es mayor o igual que", - "lessThan": "es menor que", - "lessThanOrEquals": "es menor o igual que" - }, - "filters": { - "label": "Filtres", - "clearAll": "Tout effacer" - }, - "fields": { - "title": "Champs", - "filterPlaceholder": "Filtrer les champs…", - "none": "Aucun champ", - "selected": "Champs sélectionnés", - "available": "Champs disponibles", - "topValues_one": "Top {{count}} valeur", - "topValues_other": "Top {{count}} valeurs", - "loading": "Chargement…", - "noValues": "Aucune valeur", - "addColumn": "Ajouter comme colonne", - "removeColumn": "Retirer la colonne du tableau", - "filterFor": "Filtrer sur la valeur", - "filterOut": "Exclure la valeur", - "empty": "(vide)" - }, - "results": { - "dataTypesFailed": "Impossible de charger les types de données.", - "endOfResults": "{{count}} événements chargés", - "loadingMore": "Chargement…", - "message": "Message", - "none": "Aucun log ne correspond à cette requête.", - "removeColumn": "Retirer {{field}}", - "retry": "Réessayer", - "searchFailed": "La recherche a échoué.", - "searching": "Recherche…", - "source": "Source", - "time": "Heure", - "scope": "Recherché dans {{dataset}} · {{dataType}}.", - "searchAllDataTypes": "Chercher dans tous les types" - }, - "detail": { - "fieldsCount_one": "{{count}} champ", - "fieldsCount_other": "{{count}} champs", - "copyJson": "Copier le JSON", - "copied": "Document copié", - "parsedFields": "Champs analysés", - "json": "JSON", - "filterFor": "Filtrer sur", - "filterOut": "Exclure", - "surrounding": "Événements environnants", - "surroundingHint": "Afficher les événements ±15 min autour de celui-ci, provenant de la même source" - }, - "view": { - "table": "Tableau", - "chart": "Graphique" - }, - "chart": { - "aggregateOn": "Agréger sur", - "per": "par", - "topValues": "— top 20 valeurs", - "building": "Construction du graphique…", - "failed": "Impossible de construire le graphique pour ce champ.", - "noData": "Aucune donnée à afficher." - }, - "intervals": { - "minute": "Minute", - "hour": "Heure", - "day": "Jour", - "week": "Semaine", - "month": "Mois", - "quarter": "Trimestre", - "year": "Année" - }, - "toast": { - "exportFailed": "L'export a échoué" - }, - "builder": { - "add": "Ajouter un filtre", - "filterValues": "Filtrer les valeurs…", - "loadingValues": "Chargement des valeurs…", - "noValues": "Aucune valeur.", - "cancel": "Annuler", - "confirm": "Ajouter", - "pickValue": "Pick a value to add the filter." - }, - "related": { - "nLogs_one": "{{count}} journal", - "nLogs_other": "{{count}} journaux", - "truncated": "Affichage des {{count}} premiers journaux liés (ensemble complet plus grand)." - }, - "saved": { - "title": "Enregistrées", - "empty": "Aucune recherche enregistrée", - "saveCurrent": "Enregistrer la recherche actuelle", - "save": "Enregistrer", - "namePlaceholder": "Nom de la recherche", - "delete": "Supprimer", - "saved": "« {{name}} » enregistrée", - "loading": "Chargement…", - "loadFailed": "Impossible de charger les recherches enregistrées", - "saveFailed": "Impossible d'enregistrer la recherche", - "deleteFailed": "Impossible de supprimer la recherche", - "unreadable": "Cette recherche enregistrée est illisible" - } - }, - "integrations": { - "title": "Intégrations", - "searchPlaceholder": "Rechercher des intégrations…", - "noMatch": "Aucune intégration ne correspond.", - "browseMarketplace": "Parcourir la marketplace", - "loading": "Chargement des intégrations…", - "addCustom": { - "title": "Ajouter une intégration personnalisée", - "description": "Créer une nouvelle source personnalisée", - "cta": "Créer" - }, - "tabs": { - "all": "Toutes", - "agents": "Agents", - "collectors": "Collecteurs", - "cloud": "Cloud", - "custom": "Personnalisée" - }, - "kind": { - "agents & syslog": "Agent", - "device": "Collecteur", - "antivirus": "Collecteur", - "other": "Collecteur", - "custom": "Personnalisée", - "cloud": "Cloud", - "utmstack modules": "Collecteur" - }, - "status": { - "configured": "Configurée", - "available": "Disponible" - }, - "card": { - "manage": "Gérer →", - "setup": "Configurer →", - "eventsPerSec": "{{rate}} é/s", - "enabled": "Activé", - "setupShort": "Configurer" - }, - "drawer": { - "manage": "Gérer", - "openDashboard": "Ouvrir le tableau de bord", - "viewEvents": "Voir les événements", - "documentation": "Documentation", - "getInstallCmd": "Obtenir la commande d'installation", - "setupCollector": "Configurer le collecteur", - "connect": "Connecter", - "configureCustom": "Configurer la source personnalisée", - "eventsRate": "{{rate}} événements/s · {{count}} en 24h", - "manageRules": "Règles", - "manageFilters": "Filtres" - }, - "setup": { - "agent": { - "howItWorksTitle": "Comment ça marche", - "howItWorksBody": "L'agent {{name}} est un petit démon qui s'exécute sur l'hôte et transfère les événements locaux à UTMStack via une connexion TLS authentifiée. Il se met à jour automatiquement et signale son état.", - "installTitle": "Installer sur {{name}}", - "installHint": "Exécutez cette commande sur chaque hôte {{name}} que vous souhaitez surveiller. Le jeton code déjà votre espace de travail actuel.", - "afterTitle": "Ce que vous verrez après l'installation", - "after1": "L'hôte apparaît sous Sources de données dans environ 60 secondes après le démarrage de l'agent.", - "after2": "La télémétrie commence à circuler vers Log Explorer, limitée à votre espace de travail.", - "after3": "L'agent auto-signale l'état de CPU / mémoire / disque à UTMStack.", - "actionLabel": "Action", - "platformLabel": "Plateforme", - "optionsLabel": "Options", - "skipCertValidation": "Ignorer la validation du certificat TLS (serveur autosigné)", - "noRemoteControl": "Désactiver l'exécution de commandes à distance sur cet hôte", - "loadingToken": "Chargement du jeton…", - "actions": { - "install": "Installer", - "uninstall": "Désinstaller" - }, - "prereqTitle": "Prérequis d'installation", - "prereqBody": "L'agent UTMStack communique avec le serveur via les ports suivants. Assurez-vous qu'ils sont ouverts entre l'hôte et UTMStack avant l'installation :", - "sensitiveWarning": "La commande ci-dessous contient un jeton d'enrôlement sensible — ne le partagez pas.", - "uninstall": { - "title": "Désinstaller l'agent", - "body": "Exécutez cette commande sur l'hôte pour arrêter et supprimer l'agent UTMStack et ses services. Elle utilise la plateforme sélectionnée ci-dessus." - }, - "macCompat": "Requiert macOS 11 (Big Sur) ou version ultérieure sur Apple Silicon (M1/M2/M3 ou plus récent). Les Mac Intel ne sont pas pris en charge." - }, - "collector": { - "howItWorksTitle": "Comment ça marche", - "howItWorksBody": "{{name}} n'exécute pas d'agent UTMStack. À la place, vous installez le collecteur UTMStack quelque part sur le réseau que votre appareil {{name}} et UTMStack peuvent atteindre. {{name}} envoie syslog au collecteur, le collecteur analyse, normalise et transfère les événements à UTMStack.", - "step1Title": "1 · Installer le collecteur UTMStack", - "step1Hint": "Exécutez sur un hôte Linux avec accès réseau depuis l'appareil {{name}}.", - "step2Title": "2 · Configurer {{name}} pour envoyer syslog", - "step2Hint": "Sur l'appareil {{name}}, pointez la transmission syslog vers l'adresse du collecteur sur {{port}}.", - "vendorDocs": "Voir les instructions spécifiques au fournisseur", - "step3Title": "3 · Vérifier", - "step3Body": "En quelques minutes, vous devriez voir les événements de {{name}} sous source : {{source}} dans Log Explorer, et une nouvelle entrée dans Sources de données.", - "endpoint": { - "title": "Détails de connexion", - "hint": "Configurez {{name}} pour transmettre ses journaux au Collector en utilisant l'hôte et le port ci-dessous." - }, - "syslog": { - "sections": { - "sendLogs": { - "title": "1 · Envoyer les journaux à UTMStack", - "body": "Configurez votre équipement pour envoyer des messages syslog via UDP (514) ou TCP (514) à l'agent UTMStack." - }, - "enableCollector": { - "title": "2 · Activer le collecteur syslog", - "body": "Activez le collecteur de journaux et l'intégration syslog dans le fichier de configuration où votre agent UTMStack est installé." - }, - "activate": { - "title": "3 · Activer", - "body": "Activez le module UTMStack pour que les événements commencent à affluer dans Log Explorer." - } - } - }, - "netflow": { - "source": "Équipement réseau", - "step1": { - "title": "Activer l'écouteur NetFlow sur le Collector", - "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir le collecteur NetFlow sur le port 2055 :", - "note": "NetFlow utilise uniquement UDP — TCP et TLS ne sont pas pris en charge pour ce protocole." - }, - "step2": { - "title": "Configurer votre équipement pour exporter NetFlow", - "body": "Dirigez l'export NetFlow de votre routeur ou pare-feu vers l'hôte Collector sur le port {{port}} UDP. L'exemple ci-dessous concerne Cisco IOS — consultez la documentation de votre fournisseur pour les autres plateformes :", - "note": "Remplacez par le nom de l'interface où le trafic doit être surveillé (ex. GigabitEthernet0/0). Appliquez en entrée/sortie sur chaque interface concernée." - } - }, - "cisco": { - "source": "Cisco ASA", - "step1": { - "title": "Activer l'écouteur Cisco ASA sur le Collector", - "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir l'écouteur de journaux Cisco ASA :", - "note": "Pour utiliser TCP à la place de UDP, remplacez udp par tcp dans la commande ci-dessus." - }, - "step2": { - "title": "Configurer Cisco ASA pour transmettre les journaux", - "body": "Sur votre Cisco ASA, activez syslog et pointez-le vers l'hôte Collector sur le port {{port}}. Exécutez ces commandes en mode EXEC privilégié (remplacez par le nom de votre interface interne ou de gestion) :" - } - }, - "ciscoSwitch": { - "source": "Cisco Switch", - "step1": { - "title": "Activer l'écouteur Cisco Switch sur le Collector", - "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir l'écouteur de journaux Cisco Switch :", - "note": "Pour utiliser TCP à la place de UDP, remplacez udp par tcp dans la commande ci-dessus." - }, - "step2": { - "title": "Configurer le commutateur pour transmettre les journaux", - "body": "En mode EXEC privilégié sur votre commutateur Cisco, activez syslog et pointez-le vers l'hôte Collector sur le port {{port}} :" - } - }, - "ciscoMeraki": { - "source": "Cisco Meraki", - "step1": { - "title": "Activer l'écouteur Cisco Meraki sur le Collector", - "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir l'écouteur de journaux Cisco Meraki :", - "note": "Pour utiliser TCP à la place de UDP, remplacez udp par tcp dans la commande ci-dessus." - }, - "step2": { - "title": "Configurer Meraki pour transmettre les journaux", - "body": "Dans le tableau de bord Meraki, accédez à Network-wide → Configure → General, faites défiler jusqu'à la section Reporting et ajoutez un serveur syslog avec l'IP du Collector et le port {{port}}. Sélectionnez tous les rôles que vous souhaitez transmettre." - } - }, - "ciscoFirepower": { - "source": "Cisco Firepower", - "step1": { - "title": "Activer l'écouteur Cisco Firepower sur le Collector", - "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir l'écouteur de journaux Cisco Firepower :", - "note": "Pour utiliser TCP à la place de UDP, remplacez udp par tcp dans la commande ci-dessus." - }, - "step2": { - "title": "Configurer Firepower pour transmettre les journaux", - "body": "Dans Firepower Management Center (FMC), accédez à Devices → Platform Settings, modifiez ou créez une politique et naviguez vers Syslog → Syslog Servers. Ajoutez l'IP du Collector avec le port {{port}} (UDP), puis assignez la politique à vos équipements et déployez." - } - }, - "vmware": { - "source": "VMware ESXi", - "step1": { - "title": "Activer l'écouteur VMware sur le Collector", - "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir l'écouteur syslog VMware ESXi. ESXi transmet via TCP :", - "note": "Pour un canal chiffré, utilisez tls à la place de tcp (chargez d'abord les certificats sur le Collector)." - }, - "step2": { - "title": "Pointer le syslog ESXi vers le Collector", - "body": "Ouvrez une session SSH/ESXi Shell sur l'hôte (ou utilisez le vSphere Client : Host → Configure → Advanced System Settings → Syslog.global.logHost). Définissez l'hôte de journalisation distant sur {{host}}:{{port}} et rechargez la configuration :", - "note": "Sur vSphere, vous pouvez alternativement définir Syslog.global.logHost sur la même valeur tcp://host:port plutôt qu'exécuter esxcli." - }, - "step3": { - "title": "Ouvrir le pare-feu ESXi pour syslog", - "body": "Autorisez le syslog sortant à travers le pare-feu ESXi afin que l'hôte puisse atteindre le Collector :" - } - }, - "as400": { - "intro": { - "title": "Fonctionnement", - "body": "Le Collecteur AS/400 est un service Linux qui se connecte directement à vos systèmes AS/400 (IBM i) et récupère les entrées du journal de sécurité, puis les transmet de manière sécurisée à UTMStack pour la corrélation et les alertes.", - "note": "Rien n'est installé sur l'AS/400 lui-même — le Collecteur s'exécute sur un hôte Linux qui dispose d'un accès réseau à vos systèmes AS/400.", - "diagram": { - "source": "vos journaux", - "edge1": "journaux", - "collector": "Collecteur AS/400", - "collectorSub": "extrait depuis AS/400", - "edge2": "sécurisé", - "utmstackSub": "alertes & corrélation" - } - }, - "install": { - "title": "Installer le Collecteur AS/400", - "body": "Exécutez cette commande sur un hôte Linux pouvant atteindre à la fois UTMStack et vos systèmes AS/400 via le réseau.", - "reuse": "Le Collecteur AS/400 est déjà installé ? Ignorez cette étape — ajoutez simplement vos serveurs au fichier de configuration à l'étape suivante." - }, - "configure": { - "title": "Ajouter vos serveurs AS/400", - "body": "Modifiez as400-config.yaml dans le répertoire d'installation du collecteur et ajoutez chaque système AS/400 que vous souhaitez surveiller :", - "note": "Vous pouvez répertorier plusieurs serveurs. Le collecteur surveille ce fichier et recharge automatiquement à l'enregistrement — aucun redémarrage nécessaire." - }, - "journal": { - "title": "Activer la journalisation d'audit sur AS/400", - "body": "Sur chaque système AS/400, assurez-vous que le journal d'audit de sécurité QAUDJRN est actif. Consultez la documentation IBM pour les étapes précises — la procédure varie selon les versions d'IBM i." - }, - "uninstall": { - "title": "Optionnel — Désinstaller le Collecteur", - "body": "Exécutez cette commande sur l'hôte où le Collecteur AS/400 est installé pour arrêter le service et supprimer tous les fichiers." - } - }, - "bitdefender": { - "intro": { - "title": "Fonctionnement", - "body": "UTMStack se connecte à Bitdefender GravityZone à l'aide de votre clé API pour configurer l'Event Push Service. GravityZone envoie ensuite les événements de sécurité directement à UTMStack pour la corrélation et les alertes.", - "diagram": { - "source": "événements d'endpoint", - "edge": "Event Push Service", - "utmstackSub": "alertes & corrélation" - }, - "note": "Aucun agent n'est installé sur GravityZone — UTMStack s'enregistre lui-même comme destination d'envoi à l'aide d'identifiants API en lecture seule." - }, - "whitelist": { - "title": "Autoriser les IP Bitdefender", - "body": "Les adresses IP Bitdefender GravityZone suivantes doivent être autorisées à travers votre pare-feu sur le port 8000 afin que l'Event Push Service puisse atteindre UTMStack :", - "note": "Ajoutez ces IP à votre pare-feu ou groupe de sécurité avant de finaliser la configuration." - }, - "apiSection": "Obtenir les identifiants API", - "api": { - "myAccount": { - "title": "Ouvrir Mon compte", - "body": "Dans la console Bitdefender GravityZone, cliquez sur Mon compte." - }, - "accessUrl": { - "title": "Noter l'URL d'accès", - "body": "Faites défiler jusqu'à la section Control Center API et enregistrez l'URL d'accès — vous la saisirez dans le formulaire d'identifiants ci-dessous. Ouvrez ensuite la section des clés API et cliquez sur Ajouter en haut du tableau." - }, - "createKey": { - "title": "Créer une clé API", - "body": "Rédigez une description pour la clé API, sélectionnez l'option Event Push Service API et cliquez sur Enregistrer. Copiez la clé générée." - } - }, - "companySection": "Obtenir les ID d'entreprise", - "company": { - "myCompany": { - "title": "Ouvrir Ma société", - "body": "Dans la console GravityZone, cliquez sur Ma société." - }, - "licensing": { - "title": "Noter les ID d'entreprise", - "body": "Ouvrez la section Licences et enregistrez les ID d'entreprise que vous souhaitez surveiller — saisissez-les séparés par des virgules dans le formulaire d'identifiants ci-dessous." - } - }, - "credentials": { - "title": "Saisir les identifiants", - "body": "Renseignez l'URL d'accès, la clé API, l'IP publique UTMStack (vers laquelle GravityZone enverra les événements) et les identifiants d'entreprise à surveiller. UTMStack vérifie les identifiants avant l'enregistrement." - }, - "fields": { - "accessUrl": { - "label": "URL d'accès GravityZone" - }, - "connectionKey": { - "label": "Clé API" - }, - "utmPublicIP": { - "label": "IP publique UTMStack" - }, - "companyIds": { - "label": "Identifiants d'entreprise (séparés par des virgules)" - } - } - }, - "eset": { - "source": "ESET Protect", - "step1": { - "title": "Activer l'écouteur ESET sur le Collector", - "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir l'écouteur syslog ESET :", - "note": "Pour utiliser TCP à la place de UDP, remplacez udp par tcp dans la commande ci-dessus." - }, - "console": { - "moreMenu": { - "title": "Ouvrir le menu Plus", - "body": "Dans la barre latérale de la console ESET Protect, cliquez sur le menu Plus." - }, - "serverConfig": { - "title": "Ouvrir les paramètres du serveur", - "body": "Sous Plus, ouvrez la section Paramètres du serveur (Configuration du serveur)." - }, - "advanced": { - "title": "Développer les paramètres avancés", - "body": "Cliquez sur Paramètres avancés pour afficher la liste complète des options de configuration." - }, - "syslog": { - "title": "Configurer le serveur Syslog", - "body": "Faites défiler jusqu'à Serveur Syslog, activez Exporter les journaux vers Syslog et définissez la destination sur l'hôte Collector au port {{port}} (UDP). ESET envoie LEEF/syslog, que le Collector ingère en tant que type de données antivirus-esmc-eset." - } - } - }, - "kaspersky": { - "source": "Kaspersky Security", - "step1": { - "title": "Activer l'écouteur Kaspersky sur le Collector", - "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir l'écouteur syslog Kaspersky :", - "note": "Pour utiliser TCP à la place de UDP, remplacez udp par tcp dans la commande ci-dessus." - }, - "console": { - "consoleSettings": { - "title": "Ouvrir les paramètres de la console → Intégration", - "body": "Dans la barre latérale de Kaspersky Security Center, ouvrez Paramètres de la console et cliquez sur le sous-menu Intégration." - }, - "siem": { - "title": "Ouvrir les paramètres d'intégration SIEM", - "body": "Sous Intégration, sélectionnez SIEM et cliquez sur le lien Paramètres pour ouvrir la configuration d'export." - }, - "configure": { - "title": "Configurer l'export SIEM", - "body": "Activez l'export et configurez Kaspersky pour envoyer les événements au format Splunk (CEF) vers l'hôte Collector sur le port {{port}} (UDP). Le Collector les ingère en tant que type de données antivirus-kaspersky." - } - } - }, - "sophos": { - "intro": { - "title": "Sophos Central — Plugin API", - "body": "Sophos Central fournit des API sécurisées pour récupérer les données d'événements et d'alertes. UTMStack se connecte à ces API pour centraliser la surveillance et améliorer votre visibilité de sécurité — aucun agent ni collector requis.", - "diagram": { - "source": "Sophos Central API", - "edge": "HTTPS API", - "utmstackSub": "Ingère & corrèle" - }, - "note": "UTMStack interroge l'API Sophos Central selon un calendrier. Assurez-vous que les identifiants API que vous créez ci-dessous disposent d'un accès en lecture aux événements et aux alertes." - }, - "apiSection": "Générer des identifiants API dans Sophos Central", - "steps": { - "apiCredentials": { - "title": "Ouvrir la gestion des identifiants API", - "body": "Dans Sophos Central Admin, accédez à Paramètres généraux → Gestion des identifiants API." - }, - "addCredential": { - "title": "Créer un nouvel identifiant", - "body": "Cliquez sur Ajouter un identifiant. Indiquez un Nom et une Description, sélectionnez le Rôle approprié, puis cliquez sur Ajouter." - }, - "copyIds": { - "title": "Copier le Client ID et le Client Secret", - "body": "Copiez le Client ID et le Client Secret et conservez-les en lieu sûr.", - "secretNote": "Le Client Secret n'est affiché qu'une seule fois. Sauvegardez-le en lieu sûr avant de fermer cette boîte de dialogue." - } - }, - "credentialsSection": "Se connecter à UTMStack", - "credentials": { - "title": "Ajouter des identifiants Sophos Central", - "body": "Saisissez les identifiants que vous venez de créer. Vous pouvez ajouter plusieurs comptes Sophos en cliquant sur Ajouter un groupe de configuration." - }, - "fields": { - "clientId": { - "label": "Client ID" - }, - "apiKey": { - "label": "Client Secret / Clé API" - } - } + "incidents": { + "title": "Incidents", + "subtitle": "Regroupez, triez et résolvez les alertes liées en incidents.", + "refresh": "Actualiser", + "count_one": "{{count}} incident", + "count_other": "{{count}} incidents", + "openNow": "ouverts actuellement", + "empty": "Aucun incident correspondant.", + "loadError": "Impossible de charger les incidents.", + "retry": "Réessayer", + "unassigned": "Non attribué", + "unknownUser": "Inconnu", + "status": { + "open": "Ouvert", + "in_review": "En revue", + "completed": "Terminé", + "merged": "Fusionné" }, - "webroot": { - "sections": { - "login": { - "title": "1 · Se connecter à la console de gestion", - "body": "Connectez-vous à la console de gestion Webroot. Elle s'ouvre sur l'onglet Sites." - }, - "openSettings": { - "title": "2 · Ouvrir les paramètres", - "body": "Cliquez sur l'onglet Paramètres." - }, - "apiAccess": { - "title": "3 · Ouvrir l'accès API", - "body": "Depuis l'onglet Abonnements, cliquez sur l'onglet Accès API." - }, - "createCredential": { - "title": "4 · Créer un identifiant client", - "body": "Cliquez sur Nouveau et renseignez le Nom et la Description. Lisez le contrat SecureAnywhere Business Solution et Unity API, puis cliquez sur Créer." - }, - "noteClientSecret": { - "title": "5 · Copier l'identifiant client et le secret", - "body": "Sauvegardez le Client ID depuis la liste et le Client Secret qui n'est affiché qu'une seule fois. Cliquez sur \"J'ai noté le secret client\" pour confirmer." - }, - "fillForm": { - "title": "6 · Remplir le formulaire", - "body": "Fournissez le client ID et le client secret à UTMStack. Vous pouvez ajouter plusieurs groupes de configuration Webroot si nécessaire." - }, - "activate": { - "title": "7 · Activer", - "body": "Activez le module UTMStack pour que les événements Webroot commencent à affluer." - } - } - }, - "sentinelOne": { - "source": "SentinelOne", - "step1": { - "title": "Activer l'écouteur SentinelOne sur le Collector", - "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir l'écouteur syslog SentinelOne. SentinelOne diffuse CEF via TCP :", - "note": "Pour un canal chiffré, utilisez tls à la place de tcp (chargez d'abord les certificats sur le Collector)." - }, - "console": { - "settings": { - "title": "Ouvrir les paramètres de SentinelOne", - "body": "Dans la barre latérale de la console de gestion SentinelOne, cliquez sur le menu Paramètres." - }, - "syslog": { - "title": "Configurer l'intégration Syslog", - "body": "Accédez à Intégrations → Syslog et activez-le. Définissez l'hôte sur {{host}} et le port sur {{port}}, conservez le format CEF, cliquez sur Test pour vérifier la connexion, puis Enregistrer." - } - } - }, - "office365": { - "intro": { - "title": "Fonctionnement", - "body": "UTMStack se connecte à Microsoft 365 via une application Azure AD enregistrée et interroge l'API Office 365 Management Activity pour les événements d'audit et de sécurité. Aucun agent n'est installé dans votre tenant.", - "diagram": { - "source": "événements d'audit et de sécurité", - "edge": "Management API", - "utmstackSub": "corrélation & alertes" - }, - "note": "UTMStack nécessite un accès API en lecture seule — aucune permission d'écriture n'est demandée." - }, - "appSection": "Enregistrement d'application Azure", - "steps": { - "azurePortal": { - "title": "Ouvrir Microsoft Entra ID", - "body": "Ouvrez le portail Azure (portal.azure.com) et cliquez sur Microsoft Entra ID." - }, - "appRegistrations": { - "title": "Accéder aux inscriptions d'applications", - "body": "Dans le menu de gauche, cliquez sur Inscriptions d'applications." - }, - "registerApp": { - "title": "Inscrire une nouvelle application", - "body": "Cliquez sur Nouvelle inscription. Nommez-la UTMStack O365 Agent, sélectionnez Comptes dans cet annuaire organisationnel uniquement (Monolocataire), puis cliquez sur S'inscrire." - }, - "clientSecret": { - "title": "Créer un secret client", - "body": "Accédez à Certificats et secrets → Nouveau secret client. Ajoutez une description, définissez l'expiration à 730 jours (24 mois), puis cliquez sur Ajouter.", - "copyNote": "Copiez immédiatement la valeur du secret — elle n'est affichée qu'une seule fois et ne peut pas être récupérée ultérieurement." - }, - "apiPermissions": { - "title": "Ajouter des autorisations pour l'API Office 365 Management", - "body": "Accédez à Autorisations API → Ajouter une autorisation et recherchez Office 365 Management APIs." - }, - "activityFeed": { - "title": "Accorder les autorisations ActivityFeed", - "body": "Sélectionnez Autorisations d'application et ajoutez ActivityFeed.Read et ActivityFeed.ReadDlp. Cliquez sur Accorder le consentement de l'administrateur et confirmez." - }, - "graphPermissions": { - "title": "Ajouter des autorisations Microsoft Graph", - "body": "De retour dans Ajouter une autorisation, cliquez sur Microsoft Graph." - }, - "delegatedPermissions": { - "title": "Ajouter des autorisations déléguées SecurityAlert", - "body": "Sélectionnez Autorisations déléguées et ajoutez SecurityAlert.Read.All et SecurityAlert.ReadWrite.All. Cliquez sur Accorder le consentement de l'administrateur et confirmez." - }, - "appPermissions": { - "title": "Ajouter des autorisations d'application SecurityAlert", - "body": "Sélectionnez Autorisations d'application et ajoutez SecurityAlert.Read.All et SecurityAlert.ReadWrite.All. Cliquez sur Accorder le consentement de l'administrateur et confirmez." - }, - "noteIds": { - "title": "Copier les identifiants de l'application", - "body": "Accédez à la Vue d'ensemble de l'application et copiez l'ID d'application (client) et l'ID de répertoire (tenant). Vous avez également besoin de la valeur secrète copiée à l'étape 4." - } - }, - "credentialsSection": "Identifiants", - "credentials": { - "title": "Connecter votre tenant Microsoft 365", - "body": "Saisissez les informations des étapes précédentes. UTMStack vérifie les identifiants avant l'enregistrement. Vous pouvez ajouter plusieurs groupes de configuration." - }, - "fields": { - "tenantId": { - "label": "ID du tenant (ID de répertoire)" - }, - "clientId": { - "label": "Client ID (ID d'application)" - }, - "clientSecret": { - "label": "Secret client" - }, - "cloudEnv": { - "label": "Environnement cloud (facultatif)", - "hint": "Commercial (par défaut), GCC, GCCHigh ou DoD" - } - } - }, - "github": { - "source": "GitHub", - "step1": { - "title": "Activer l'écouteur de webhook GitHub sur le Collector", - "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir l'écouteur de webhook HTTPS pour GitHub :", - "tokenNote": "Le terminal affichera un jeton secret — copiez-le immédiatement. Il ne sera plus affiché." - }, - "certWarning": { - "title": "GitHub exige un certificat TLS signé par une autorité de certification", - "body": "GitHub n'envoie des webhooks qu'aux points de terminaison HTTPS disposant d'un certificat émis par une autorité de certification publique (les certificats auto-signés sont refusés). Assurez-vous que l'hôte du Collector possède un certificat de domaine valide avant d'enregistrer le webhook." - }, - "step2": { - "title": "Enregistrer le webhook dans GitHub", - "body": "Dans votre dépôt ou organisation, allez dans Settings → Webhooks → Add webhook et remplissez le formulaire :", - "payloadUrl": "URL de payload", - "contentType": "Type de contenu", - "secret": "Secret", - "secretHint": "Collez le jeton affiché par le Collector à l'étape précédente.", - "events": "Quels événements", - "eventsHint": "Tout envoyer — ou sélectionner des types d'événements spécifiques." - } - }, - "salesforce": { - "sections": { - "openSetup": { - "title": "1 · Ouvrir Setup", - "body": "Accédez à Setup et sélectionnez « Setup for the current app » en haut à droite de l'écran." - }, - "appManager": { - "title": "2 · Ouvrir App Manager", - "body": "Saisissez « App Manager » dans la zone de recherche rapide et sélectionnez App Manager." - }, - "newConnectedApp": { - "title": "3 · Créer une nouvelle Connected App", - "body": "Sur l'écran Lightning Experience App Manager, cliquez sur « New Connected App » et remplissez les champs." - }, - "oauthSettings": { - "title": "4 · Activer les paramètres OAuth", - "body": "Dans la section « API (Enable OAuth Settings) », cochez « Enable OAuth Settings » et utilisez https://login.salesforce.com/services/oauth2/success comme URL de rappel." - }, - "oauthScopes": { - "title": "5 · Ajouter des portées OAuth", - "body": "Sélectionnez « Access Connect REST API resources (chatter_api) » sous Selected OAuth Scopes." - }, - "save": { - "title": "6 · Enregistrer", - "body": "Enregistrez vos modifications et sélectionnez Continue sur l'écran suivant." - }, - "manageConsumer": { - "title": "7 · Ouvrir Manage Consumer Details", - "body": "Dans votre Connected App, allez dans « API (Enable OAuth Settings) » et cliquez sur « Manage Consumer Details » à côté de Consumer Key and Secret." - }, - "copyCredentials": { - "title": "8 · Copier la clé et le secret consommateur", - "body": "Vérifiez votre identité. La Consumer Key et le Consumer Secret apparaissent sous « Consumer Details ». Copiez les deux avec le bouton Copy." - }, - "fillForm": { - "title": "9 · Remplir le formulaire", - "body": "Fournissez la Consumer Key, le Consumer Secret, le nom d'utilisateur Salesforce et le mot de passe à UTMStack." - }, - "activate": { - "title": "10 · Activer", - "body": "Activez le module UTMStack pour que les événements Salesforce commencent à affluer." - } - } + "sev": { + "high": "Élevée", + "medium": "Moyenne", + "low": "Faible", + "unknown": "Non évaluée" }, - "iis": { - "sections": { - "enableModule": { - "title": "1 · Activer le module IIS Filebeat", - "body": "Sur l'hôte de l'agent UTMStack, exécutez :\ncd \"C:\\Program Files\\UTMStack\\UTMStack Agent\\beats\\filebeat\\\" && filebeat modules enable iis" - }, - "configureModule": { - "title": "2 · Configurer le module IIS", - "body": "Modifiez C:\\Program Files\\UTMStack\\UTMStack Agent\\beats\\filebeat\\modules.d\\iis.yml comme indiqué ci-dessous pour pointer vers les répertoires de journaux IIS que vous souhaitez transmettre." - }, - "activate": { - "title": "3 · Activer", - "body": "Activez le module UTMStack pour que les événements IIS commencent à affluer." - } - } + "toolbar": { + "search": "Rechercher des incidents…", + "create": "Créer un incident", + "allSeverities": "Toutes les sévérités", + "export": "Exporter en CSV" }, - "filebeat": { - "sections": { - "installRsyslog": { - "title": "1 · Installer rsyslog", - "body": "Assurez-vous que rsyslog est installé sur l'hôte. Utilisez le gestionnaire de paquets de votre distribution (apt, dnf, yum)." - }, - "configureRsyslog": { - "title": "2 · Configurer rsyslog pour transférer vers UTMStack", - "body": "Modifiez /etc/rsyslog.conf (ou un fichier sous /etc/rsyslog.d/) et ajoutez une règle de transfert ciblant l'agent UTMStack via UDP ou TCP sur le port 514." - }, - "restartRsyslog": { - "title": "3 · Redémarrer rsyslog", - "body": "Redémarrez le service rsyslog : sudo systemctl restart rsyslog" - }, - "enableCollector": { - "title": "4 · Activer le collecteur de journaux Linux", - "body": "Activez le collecteur de journaux et l'intégration Linux Logs dans le fichier de configuration où votre agent UTMStack est installé." - } - } + "statusTabs": { + "all": "Tous" }, - "json": { - "sections": { - "overview": { - "title": "1 · Utiliser le point de terminaison d'ingestion HTTP/JSON", - "body": "UTMStack accepte des événements JSON arbitraires via HTTPS. Envoyez une requête POST avec une liste d'événements ; UTMStack les analyse et les achemine via votre analyseur configuré." - }, - "auth": { - "title": "2 · S'authentifier avec un jeton de fédération", - "body": "Obtenez un jeton de fédération depuis Settings → Connection Key et envoyez-le comme jeton Bearer dans l'en-tête Authorization." - } - }, - "endpoint": { - "title": "Point de terminaison d'ingestion JSON", - "hint": "Utilisez cette structure de requête depuis votre application ou une tâche cron. Le jeton est la clé de fédération issue de Settings → Connection Key." - } - }, - "ldap": { - "sections": { - "openServerManager": { - "title": "1 · Ouvrir Server Manager", - "body": "Sur le contrôleur de domaine AD, ouvrez Server Manager." - }, - "addRoles": { - "title": "2 · Ajouter des rôles et des fonctionnalités", - "body": "Choisissez « Add roles and features » dans le menu Manage." - }, - "selectCertServices": { - "title": "3 · Sélectionner Active Directory Certificate Services", - "body": "À l'étape Server Roles, sélectionnez Active Directory Certificate Services." - }, - "installServices": { - "title": "4 · Installer le service de rôle Autorité de certification", - "body": "À l'étape Role Services, sélectionnez Certificate Authority et terminez l'assistant." - }, - "configureAdCs": { - "title": "5 · Configurer AD CS", - "body": "Après l'installation, cliquez sur la notification pour configurer AD CS et choisissez Certificate Authority comme service de rôle à configurer." - }, - "pickCaType": { - "title": "6 · Choisir le type d'autorité de certification", - "body": "Choisissez Enterprise CA → Root CA → Create a new private key." - }, - "setValidity": { - "title": "7 · Définir la période de validité du certificat", - "body": "Définissez une période de validité adaptée à votre organisation (5 ans est courant)." - }, - "confirm": { - "title": "8 · Confirmer et installer", - "body": "Vérifiez les paramètres et cliquez sur Configure pour terminer." - }, - "restart": { - "title": "9 · Redémarrer le contrôleur de domaine", - "body": "Redémarrez le contrôleur de domaine pour que LDAPS devienne disponible sur TCP 636." - }, - "activate": { - "title": "10 · Activer", - "body": "Activez le module UTMStack pour que les événements d'audit AD commencent à affluer." - } - } - }, - "oracle": { - "source": "Serveur Oracle DB", - "step1": { - "title": "Activer l'intégration Oracle sur le Collector", - "body": "Sur le serveur où le Collector est installé, exécutez la commande suivante pour commencer à écouter les journaux Oracle :", - "note": "Le Collector commencera à recevoir des événements syslog d'Oracle sur le port 7021." - }, - "step2": { - "title": "Configurer rsyslog sur le serveur Oracle", - "body": "Créez le fichier de configuration rsyslog :", - "editBody": "Ouvrez le fichier avec votre éditeur préféré et ajoutez la configuration suivante. Remplacez BASEDIR par votre chemin d'installation Oracle (p. ex., /u01/app/oracle) et par l'adresse IP ou le nom d'hôte du Collector :", - "note": "Utilisez @@:7021 au lieu de @ si vous préférez une livraison TCP." - }, - "step3": { - "title": "Redémarrer rsyslog", - "body": "Appliquez la nouvelle configuration en redémarrant le service rsyslog :" - }, - "step4": { - "title": "Valider la configuration", - "body": "Envoyez des messages de journal de test pour vérifier qu'UTMStack reçoit des événements des trois sources de journaux Oracle :", - "note": "Ouvrez Log Explorer et recherchez le texte du message de test ci-dessus pour confirmer leur réception." - } - }, - "vulnerabilities": { - "sections": { - "overview": { - "title": "1 · À propos du scanner de vulnérabilités", - "body": "Le module de vulnérabilités UTMStack analyse les actifs découverts via le module Asset Management et compare leur empreinte à la base de données CVE." - }, - "scope": { - "title": "2 · Définir la portée de l'analyse", - "body": "Utilisez le module Asset Management pour enregistrer les hôtes que vous souhaitez analyser. Le scanner de vulnérabilités s'exécutera périodiquement sur ces hôtes." - }, - "activate": { - "title": "3 · Activer", - "body": "Activez le module UTMStack pour démarrer l'analyse." - } - } + "filters": { + "add": "Ajouter un filtre", + "clearAll": "Tout effacer", + "filterValues": "Filtrer les valeurs…", + "loadingValues": "Chargement des valeurs…", + "noValues": "Aucune valeur trouvée.", + "pickValue": "Choisissez une valeur pour ajouter le filtre.", + "empty": "(vide)", + "cancel": "Annuler", + "addBtn": "Ajouter" }, - "assetScanner": { - "sections": { - "overview": { - "title": "1 · À propos d'Asset Management", - "body": "Le module Asset Management découvre et inventorie les hôtes, les logiciels et les services sur votre réseau." - }, - "agentRequirement": { - "title": "2 · Exigence d'agent", - "body": "La découverte des actifs utilise des agents UTMStack installés sur des hôtes Linux, Windows ou macOS. Installez l'agent sur les systèmes que vous souhaitez inventorier." - }, - "activate": { - "title": "3 · Activer", - "body": "Activez le module UTMStack pour démarrer la découverte des actifs." - } - } + "ops": { + "IS": "est" }, - "fileIntegrity": { - "sections": { - "enableAuditPolicy": { - "title": "1 · Activer l'audit d'accès aux objets", - "body": "Sur l'hôte Windows, ouvrez Group Policy → Computer Configuration → Windows Settings → Security Settings → Advanced Audit Policy Configuration → Object Access et activez « Audit File System »." - }, - "configureFolderAuditing": { - "title": "2 · Configurer l'audit des dossiers", - "body": "Pour chaque dossier à surveiller, ouvrez Properties → Security → Advanced → Auditing et ajoutez une entrée d'audit pour les principaux et les types d'accès souhaités." - }, - "verifyEvents": { - "title": "3 · Vérifier l'apparition des événements dans le journal de sécurité", - "body": "Ouvrez Event Viewer et confirmez que les événements 4663/4670 sont générés lors de l'accès aux objets audités." - }, - "activate": { - "title": "4 · Activer", - "body": "Activez le module UTMStack pour que les événements d'intégrité de fichiers commencent à transiter." - } - } + "layout": { + "table": "Tableau", + "board": "Kanban" }, - "socAi": { - "sections": { - "overview": { - "title": "1 · À propos de SOC AI", - "body": "SOC AI enrichit UTMStack avec un analyste basé sur LLM qui résume les alertes et suggère les prochaines étapes. Il fonctionne avec le fournisseur que vous configurez." - }, - "chooseProvider": { - "title": "2 · Choisir un fournisseur", - "body": "Sélectionnez un fournisseur — OpenAI, Anthropic, Azure OpenAI, Google Gemini, Ollama, Mistral, DeepSeek, Groq, ou un point de terminaison compatible OpenAI personnalisé." - }, - "configureCredentials": { - "title": "3 · Configurer les identifiants", - "body": "Fournissez la clé API et, le cas échéant, le nom du modèle et l'URL du point de terminaison." - }, - "activate": { - "title": "4 · Activer", - "body": "Activez le module UTMStack pour que SOC AI commence à traiter les alertes." - } - } - }, - "utmstack": { - "intro": { - "title": "Fonctionnement", - "body": "Cette intégration surveille votre déploiement UTMStack en auto-surveillance. Un collecteur léger installé sur l'hôte UTMStack suit les journaux des conteneurs Docker de la plateforme et les renvoie vers UTMStack pour corrélation et alertes.", - "diagram": { - "source": "Journaux Docker", - "sourceSub": "Conteneurs UTMStack", - "edge1": "suivi", - "collector": "Collecteur", - "collectorSub": "sur l'hôte", - "edge2": "ingestion", - "utmstackSub": "Corrèle et alerte" - } - }, - "requirements": { - "title": "Fonctionne uniquement sur l'hôte UTMStack", - "body": "Cette intégration ne peut être installée que sur une instance UTMStack fonctionnant sous Ubuntu ou une distribution de la famille Red Hat. Installez le collecteur directement sur le serveur UTMStack." - }, - "install": { - "title": "Installer le collecteur", - "body": "Sur l'hôte UTMStack, sélectionnez votre système d'exploitation et exécutez la commande ci-dessous pour télécharger et installer le collecteur d'auto-surveillance :", - "sensitiveWarning": "Cette commande contient un jeton de connexion sensible. Traitez-le comme un mot de passe et ne le partagez pas." - }, - "after": { - "title": "Ce que vous verrez après l'installation", - "item1": "Le collecteur s'enregistre et apparaît sous Sources de données.", - "item2": "Les journaux des conteneurs UTMStack commencent à transiter en moins d'une minute.", - "item3": "Les événements deviennent consultables dans Log Explorer sous le type de données utmstack." - }, - "uninstall": { - "title": "Désinstaller le collecteur", - "body": "Pour supprimer le collecteur d'auto-surveillance de l'hôte UTMStack, exécutez :" - } - }, - "windowsFaa": { - "sections": { - "enableAuditPolicy": { - "title": "1 · Activer l'audit d'accès aux objets", - "body": "Sur l'hôte Windows, ouvrez Group Policy → Computer Configuration → Windows Settings → Security Settings → Advanced Audit Policy Configuration → Object Access et activez « Audit File System »." - }, - "configureFolderAuditing": { - "title": "2 · Configurer l'audit des dossiers", - "body": "Pour chaque dossier à surveiller, ouvrez Properties → Security → Advanced → Auditing et ajoutez une entrée d'audit pour les principaux et les types d'accès souhaités." - }, - "activate": { - "title": "3 · Activer", - "body": "Activez le module UTMStack pour que les événements d'activité de fichiers commencent à transiter." - } - } + "table": { + "name": "Incident", + "status": "Statut", + "severity": "Sévérité", + "assignee": "Assigné", + "alerts": "Alertes", + "created": "Créé" }, - "awsBeanstalk": { - "sections": { - "openConsole": { - "title": "1 · Ouvrir la console Elastic Beanstalk", - "body": "Dans la console AWS, ouvrez Elastic Beanstalk." - }, - "environment": { - "title": "2 · Ouvrir la page de gestion de l'environnement", - "body": "Accédez à la page de gestion de l'environnement que vous souhaitez surveiller." - }, - "configuration": { - "title": "3 · Ouvrir la configuration", - "body": "Sélectionnez Configuration." - }, - "software": { - "title": "4 · Modifier la configuration logicielle", - "body": "Dans la catégorie Software configuration, sélectionnez Modify." - }, - "s3LogStorage": { - "title": "5 · Activer le stockage des journaux S3", - "body": "Sous S3 log storage, sélectionnez Rotate logs pour téléverser les journaux pivotés vers Amazon S3." - }, - "cloudwatchStreaming": { - "title": "6 · Activer le streaming CloudWatch Logs", - "body": "Sous Instance log streaming to CloudWatch Logs, activez le streaming, définissez la période de rétention et choisissez si vous souhaitez téléverser les journaux existants." - }, - "activate": { - "title": "7 · Activer", - "body": "Activez le module UTMStack pour que les événements Beanstalk commencent à transiter." + "drawer": { + "created": "Créé {{date}}", + "alertsCount": "{{count}} alertes", + "solutionPlaceholder": "Résolution / notes de remédiation…", + "solutionHint": "Enregistré lors du passage de l’incident à Terminé.", + "tabs": { + "overview": "Aperçu", + "alerts": "Alertes", + "notes": "Notes", + "history": "Historique" + }, + "section": { + "description": "Description", + "solution": "Solution", + "details": "Détails" + }, + "details": { + "id": "ID", + "status": "Statut", + "severity": "Sévérité", + "assignee": "Assigné", + "created": "Créé", + "alerts": "Alertes liées" } - } }, - "awsFargate": { - "sections": { - "taskDefinition": { - "title": "1 · Mettre à jour la définition de tâche", - "body": "Dans la définition de tâche pour la tâche Fargate, définissez le logDriver sur « awslogs » et spécifiez le nom du groupe de journaux." - }, - "cloudwatchLogs": { - "title": "2 · Confirmer que CloudWatch Logs reçoit les journaux", - "body": "Ouvrez la console CloudWatch Logs et confirmez que le groupe de journaux est alimenté lors de l'exécution des tâches." - }, - "iamPrerequisite": { - "title": "3 · Prérequis utilisateur IAM", - "body": "Cette intégration partage les identifiants avec le module AWS IAM User — assurez-vous qu'il est configuré avec CloudWatchLogsReadOnlyAccess." - }, - "activate": { - "title": "4 · Activer", - "body": "Activez le module UTMStack pour que les événements Fargate commencent à transiter." - } - } + "alerts": { + "empty": "Aucune alerte liée à cet incident.", + "remove": "Dissocier l’alerte", + "removeConfirm": "Dissocier « {{name}} » de cet incident ?", + "removed": "Alerte dissociée", + "removeError": "Impossible de dissocier l’alerte", + "loadingAlert": "Chargement de l'alerte…", + "alertGone": "Cette alerte n'est plus dans le stockage — la rétention l'a peut-être supprimée.", + "alertFailed": "Impossible de charger l'alerte.", + "openInAlerts": "Ouvrir dans Alertes" }, - "awsIamUser": { - "sections": { - "iamConsole": { - "title": "1 · Ouvrir la console IAM", - "body": "Dans la console AWS, accédez à IAM → Users → Add users." - }, - "createUser": { - "title": "2 · Créer l'utilisateur", - "body": "Choisissez un nom d'utilisateur (ex. utmstack-ingest). Sélectionnez l'accès programmatique." - }, - "programmaticAccess": { - "title": "3 · Définir le type d'identifiant", - "body": "Sélectionnez « Access key — Programmatic access »." - }, - "attachPolicy": { - "title": "4 · Attacher la politique de lecture CloudWatch", - "body": "Attachez la politique gérée par AWS CloudWatchLogsReadOnlyAccess." - }, - "review": { - "title": "5 · Vérifier l'utilisateur", - "body": "Vérifiez les détails de l'utilisateur et cliquez sur Create user." - }, - "copyKeys": { - "title": "6 · Copier l'identifiant de clé d'accès et le secret", - "body": "Copiez l'Access key ID et la Secret access key — le secret n'est affiché qu'une seule fois." - }, - "createLogGroup": { - "title": "7 · Créer un groupe de journaux CloudWatch", - "body": "Dans CloudWatch → Log groups, créez un groupe de journaux nommé « utmstack » — les autres intégrations AWS y enverront leurs données." - }, - "fillForm": { - "title": "8 · Remplir le formulaire", - "body": "Fournissez la clé d'accès, le secret, la région par défaut et le nom du groupe de journaux (ex. « utmstack ») à UTMStack." - }, - "activate": { - "title": "9 · Activer", - "body": "Activez le module UTMStack pour que les événements AWS commencent à transiter." - } - } + "notes": { + "empty": "Pas encore de notes.", + "add": "Ajouter une note", + "addError": "Impossible d’ajouter la note", + "placeholder": "Écrire une note…" }, - "awsLambda": { - "sections": { - "iamPrerequisite": { - "title": "1 · Prérequis utilisateur IAM", - "body": "Lambda repose sur le module AWS IAM User — assurez-vous que cette intégration est configurée en premier avec CloudWatchLogsReadOnlyAccess." - }, - "cloudwatchStream": { - "title": "2 · Lambda diffuse déjà vers CloudWatch Logs", - "body": "AWS Lambda publie automatiquement les journaux d'exécution dans CloudWatch Logs sous /aws/lambda/. UTMStack ingère depuis le groupe de journaux configuré lors de la configuration de l'utilisateur IAM." - }, - "activate": { - "title": "3 · Activer", - "body": "Activez le module UTMStack pour que les événements Lambda commencent à transiter." - } - } + "history": { + "empty": "Pas encore d’historique." }, - "awsSqlServer": { - "sections": { - "openRds": { - "title": "1 · Ouvrir la console Amazon RDS", - "body": "Ouvrez https://console.aws.amazon.com/rds/." - }, - "pickDb": { - "title": "2 · Sélectionner l'instance de base de données", - "body": "Dans le volet de navigation, sélectionnez Databases et choisissez l'instance de base de données à surveiller." - }, - "modify": { - "title": "3 · Modifier l'instance", - "body": "Sélectionnez Modify." - }, - "logExports": { - "title": "4 · Activer les exportations de journaux", - "body": "Dans la section Log exports, sélectionnez Error log et Agent log pour publier dans CloudWatch Logs." - }, - "apply": { - "title": "5 · Appliquer les modifications", - "body": "Cliquez sur Continuer, puis sur Modifier l'instance DB sur la page de récapitulatif." - }, - "activate": { - "title": "6 · Activer", - "body": "Activez le module UTMStack pour que les événements SQL Server commencent à affluer." - } - } + "toast": { + "statusChanged": "Statut de l’incident mis à jour", + "statusError": "Impossible de changer le statut", + "exportFailed": "Échec de l'export CSV" }, - "awsPostgresql": { - "sections": { - "openRds": { - "title": "1 · Ouvrir la console Amazon RDS", - "body": "Ouvrez https://console.aws.amazon.com/rds/." - }, - "pickDb": { - "title": "2 · Sélectionner l'instance DB", - "body": "Dans le panneau de navigation, sélectionnez Databases et choisissez l'instance DB à modifier." - }, - "logExports": { - "title": "3 · Activer les exportations de journaux", - "body": "Dans la section Log exports, sélectionnez le journal PostgreSQL à publier dans CloudWatch Logs." - }, - "apply": { - "title": "4 · Appliquer les modifications", - "body": "Cliquez sur Continuer, puis sur Modifier l'instance DB sur la page de récapitulatif." - }, - "activate": { - "title": "5 · Activer", - "body": "Activez le module UTMStack pour que les événements PostgreSQL commencent à affluer." - } - } + "assign": { + "assign": "Assigner", + "search": "Rechercher des utilisateurs…", + "unassign": "Désassigner", + "noUsers": "Aucun utilisateur", + "assigned": "Assigné à {{user}}", + "unassigned": "Incident désassigné", + "error": "Impossible de changer l’assigné", + "custom": "Assigner personnalisé", + "customPlaceholder": "Saisir un identifiant…" }, - "awsTrafficMirror": { - "sections": { - "createTarget": { - "title": "1 · Créer une cible de mise en miroir du trafic", - "body": "Dans la console VPC, créez un Traffic Mirror Target pointant vers l'interface réseau de la VM de l'agent UTMStack." - }, - "createFilter": { - "title": "2 · Créer un filtre de mise en miroir du trafic", - "body": "Créez un Traffic Mirror Filter et ajoutez des règles entrantes/sortantes pour les protocoles à mettre en miroir (ex. tout TCP, tout UDP)." - }, - "createSession": { - "title": "3 · Créer une session de mise en miroir du trafic", - "body": "Créez une Traffic Mirror Session associant chaque interface réseau source à la cible et au filtre créés." - }, - "iamPrerequisite": { - "title": "4 · Prérequis utilisateur IAM", - "body": "Assurez-vous que le module AWS IAM User est également configuré afin que UTMStack puisse lire les journaux de flux VPC si nécessaire." - }, - "activate": { - "title": "5 · Activer", - "body": "Activez le module UTMStack pour que le trafic mis en miroir commence à être analysé." - } - } - }, - "forwarder": { - "intro": { - "title": "Fonctionnement", - "body": "Les journaux transitent de {{source}} vers le UTMStack Collector, qui les envoie de manière sécurisée dans UTMStack pour la corrélation et les alertes. Rien n'est installé sur {{source}} — seul le Collector doit être exécuté sur un hôte de votre réseau." - }, - "diagram": { - "sourceSub": "vos journaux", - "forwarder": "Collector", - "forwarderSub": "écoute sur {{port}}", - "utmstack": "UTMStack", - "utmstackSub": "alertes & corrélation", - "flow1": "journaux", - "flow2": "sécurisé" - }, - "noInstall": "Rien n'est installé sur {{source}} — vous redirigez uniquement ses journaux vers le Collector.", - "install": { - "title": "Installer le UTMStack Collector", - "body": "Le Collector est un service Linux qui reçoit les journaux de vos appareils et les envoie à UTMStack. Un seul Collector gère plusieurs intégrations simultanément.", - "reuse": "Vous avez déjà un Collector en cours d'exécution ? Ignorez cette étape — redirigez {{source}} vers celui existant en utilisant l'hôte et le port indiqués ci-dessous." - }, - "tls": { - "title": "Optionnel — Activer le chiffrement TLS", - "intro": "Par défaut, le listener accepte du TCP/UDP en clair. Pour chiffrer le trafic syslog en transit, chargez d'abord vos fichiers de certificat, puis réactivez le listener avec le protocole tls.", - "step1": "1 · Charger votre certificat et votre clé (une fois par Collector)", - "step1Note": "Un certificat CA facultatif peut être ajouté comme troisième argument. Omettez-le pour utiliser le certificat feuille comme CA.", - "step2": "2 · Réactiver le listener avec TLS" - }, - "httpsCerts": { - "title": "Chargez le certificat TLS sur le Collector", - "body": "Cette intégration utilise un listener HTTPS sur le port {{port}}, le Collector a donc besoin d'un certificat et d'une clé chargés avant de l'activer :" - }, - "uninstall": { - "title": "Optionnel — Désinstaller le Collector", - "body": "Exécutez cette commande sur l'hôte où le Collector est installé pour arrêter le service et supprimer tous ses fichiers." - }, - "instanceHeader": { - "title": "En-tête d'autorisation", - "body": "Incluez cet en-tête Authorization dans chaque requête envoyée à l'instance. Le secret de la clé API n'est révélé qu'une seule fois à sa génération — copiez-le à ce moment et collez-le à la place du placeholder ci-dessous.", - "tabSimple": "Simple", - "tabBatch": "Lot" - }, - "manualCommand": { - "title": "Optional — Enable via the command line instead", - "intro": "Prefer the terminal? SSH into the Collector host and run the command below — it matches whatever protocol and port you have selected above.", - "certStep": "1 · Load your certificate and key (once per Collector)", - "enableStep": "2 · Enable the integration" - } - }, - "aix": { - "source": "Serveur AIX", - "step1": { - "title": "Activer le listener AIX sur le Collector", - "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir le listener de journaux AIX :", - "note": "Pour utiliser TCP au lieu de UDP, remplacez udp par tcp dans la commande ci-dessus." - }, - "step2": { - "title": "Configurer AIX pour transmettre les journaux", - "body": "Sur votre système AIX, configurez le service syslog pour rediriger ses journaux vers l'hôte du Collector sur le port {{port}}. Consultez la documentation IBM pour la syntaxe exacte — elle varie selon les versions d'AIX." - } - }, - "deceptivebytes": { - "source": "Deceptive Bytes", - "step1": { - "title": "Activer le listener Deceptive Bytes sur le Collector", - "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir le listener syslog Deceptive Bytes :", - "note": "Pour utiliser TCP au lieu de UDP, remplacez udp par tcp dans la commande ci-dessus." - }, - "step2": { - "title": "Configurer Deceptive Bytes pour transmettre les journaux", - "body": "Dans la console de gestion Deceptive Bytes, configurez le transfert syslog pour envoyer les événements à l'hôte du Collector sur le port {{port}} (UDP). Deceptive Bytes émet du syslog au format CEF, que le Collector ingère sous le type de données deceptive-bytes." - } - }, - "mikrotik": { - "source": "Routeur MikroTik", - "step1": { - "title": "Activer le listener MikroTik sur le Collector", - "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir le listener syslog MikroTik :", - "note": "Pour utiliser TCP au lieu de UDP, remplacez udp par tcp dans la commande ci-dessus." - }, - "step2": { - "title": "Configurer MikroTik pour transmettre les journaux", - "body": "Sur le routeur MikroTik, créez une action de journalisation distante pointant vers l'hôte du Collector sur le port {{port}} et associez-la aux rubriques de journaux pertinentes. Exécutez la commande suivante depuis le CLI RouterOS (Terminal dans Winbox) :", - "note": "Vous pouvez également configurer cela via Winbox : System → Logging → onglet Actions (ajouter une action Remote) → puis l'onglet Rules (ajouter des règles pointant vers la nouvelle action)." - } - }, - "fortigate": { - "source": "Pare-feu FortiGate", - "step1": { - "title": "Activer le listener FortiGate sur le Collector", - "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir le listener syslog FortiGate :", - "note": "Pour utiliser TCP au lieu de UDP, remplacez udp par tcp dans la commande ci-dessus." - }, - "step2": { - "title": "Configurer FortiGate pour transmettre les journaux", - "body": "Sur le FortiGate, pointez syslog vers l'hôte du Collector sur le port {{port}}. Exécutez la commande suivante depuis le CLI FortiOS (ou utilisez Log & Report → Log Settings → Syslog dans l'interface graphique) :", - "note": "Remplacez l'adresse du serveur si le Collector s'exécute sur un hôte différent. Pour plusieurs collecteurs syslog, utilisez syslogd2/syslogd3/syslogd4." - } - }, - "fortiweb": { - "source": "FortiWeb WAF", - "step1": { - "title": "Activer le listener FortiWeb sur le Collector", - "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir le listener syslog FortiWeb :", - "note": "Pour utiliser TCP au lieu de UDP, remplacez udp par tcp dans la commande ci-dessus." - }, - "step2": { - "title": "Configurer FortiWeb pour transmettre les journaux", - "body": "Sur le FortiWeb, créez une politique syslog pointant vers l'hôte du Collector sur le port {{port}} et activez la journalisation syslog. Exécutez la commande suivante depuis le CLI FortiWeb (ou utilisez Log & Report → Log Policy → Syslog Policy dans l'interface graphique) :", - "note": "Assurez-vous que les types de journaux pertinents (Attack, Event, Traffic) sont activés pour être envoyés à syslog dans les paramètres Log & Report." - } - }, - "paloalto": { - "source": "Pare-feu Palo Alto", - "step1": { - "title": "Activer le listener Palo Alto sur le Collector", - "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir le listener syslog Palo Alto :", - "note": "Pour utiliser TCP au lieu de UDP, remplacez udp par tcp dans la commande ci-dessus." - }, - "step2": { - "title": "Créer un profil de serveur Syslog", - "body": "Dans PAN-OS, accédez à Device → Server Profiles → Syslog et ajoutez un profil. Définissez l'adresse du serveur sur {{host}}, le transport sur UDP, le port sur {{port}} et le format sur BSD." - }, - "step3": { - "title": "Transmettre les journaux et valider", - "body": "Créez un profil Log Forwarding (Objects → Log Forwarding) qui envoie les journaux Traffic, Threat et d'autres types au profil syslog ci-dessus, associez-le à vos règles de Security policy (Policies → Security → règle → Actions → Log Forwarding), puis Commit." - } - }, - "pfsense": { - "source": "Pare-feu pfSense", - "step1": { - "title": "Activer le listener pfSense sur le Collector", - "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir le listener syslog pfSense :", - "note": "Pour utiliser TCP au lieu de UDP, remplacez udp par tcp dans la commande ci-dessus." - }, - "step2": { - "title": "Activer la journalisation distante dans pfSense", - "body": "Dans l'interface web pfSense, accédez à Status → System Logs → Settings. Sous Remote Logging Options, cochez Enable Remote Logging, définissez un serveur de journaux distant sur {{host}}:{{port}}, choisissez les journaux à envoyer (ou Everything), puis cliquez sur Save." - } - }, - "sonicwall": { - "source": "Pare-feu SonicWall", - "step1": { - "title": "Activer le listener SonicWall sur le Collector", - "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir le listener syslog SonicWall :", - "note": "Pour utiliser TCP au lieu de UDP, remplacez udp par tcp dans la commande ci-dessus." - }, - "step2": { - "title": "Ajouter un serveur Syslog dans SonicOS", - "body": "Dans SonicOS, accédez à Device → Log → Syslog (Manage → Log → Syslog sur les anciens firmwares) et ajoutez un serveur Syslog avec l'adresse {{host}} et le port {{port}}. Définissez le Syslog Format sur ArcSight (CEF) — UTMStack analyse SonicWall en CEF — puis cliquez sur Apply." - } - }, - "sophosxg": { - "source": "Sophos Firewall", - "step1": { - "title": "Activer le listener Sophos Firewall sur le Collector", - "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir le listener syslog Sophos Firewall :", - "note": "Pour utiliser TCP au lieu de UDP, remplacez udp par tcp dans la commande ci-dessus." - }, - "step2": { - "title": "Ajouter un serveur Syslog dans Sophos Firewall", - "body": "Dans la console Sophos Firewall (SFOS), accédez à System → System services → Log settings et ajoutez un serveur Syslog avec l'adresse {{host}} et le port {{port}}. Choisissez les types de journaux à transmettre (firewall, IPS, ATP, web, etc.) et cliquez sur Apply." - } - }, - "suricata": { - "source": "Suricata IDS", - "step1": { - "title": "Activer l'écouteur Suricata sur le Collector", - "body": "Sur l'hôte où le Collector est installé, exécutez cette commande pour ouvrir l'écouteur Suricata :", - "note": "Pour utiliser TCP à la place de UDP, remplacez udp par tcp dans la commande ci-dessus." - }, - "step2": { - "title": "Envoyer les journaux EVE de Suricata vers syslog", - "body": "Suricata est ingéré en JSON (EVE). Sur l'hôte Suricata, modifiez suricata.yaml et configurez la sortie eve-log pour écrire vers syslog :", - "note": "Puis redémarrez Suricata : sudo systemctl restart suricata" - }, - "step3": { - "title": "Transmettre syslog vers le Collector", - "body": "Dirigez la facility local5 (vers laquelle Suricata écrit désormais) vers le Collector. Ajoutez cette règle dans /etc/rsyslog.d/60-utmstack-suricata.conf sur l'hôte Suricata :", - "note": "Utilisez @@ au lieu de @ pour TCP. Puis redémarrez rsyslog : sudo systemctl restart rsyslog" - } - }, - "o365_graph": { - "intro": { - "title": "Comment ça fonctionne", - "body": "UTMStack se connecte à Microsoft 365 avec une app Azure AD enregistrée et interroge Microsoft Graph pour les événements de sécurité : alertes, incidents, audit du répertoire, sign-ins, détections de risque, requêtes de hunting et journaux d'audit Purview. Aucun agent n'est installé dans votre tenant.", - "diagram": { - "source": "événements de sécurité", - "edge": "Microsoft Graph", - "utmstackSub": "corrélation & alertes" - }, - "note": "UTMStack nécessite un accès en lecture seule à l'API Graph — aucune permission d'écriture n'est demandée." - }, - "appSection": "Enregistrement d'application Azure", - "steps": { - "azurePortal": { - "title": "Ouvrir Microsoft Entra ID", - "body": "Ouvrez le Portail Azure (portal.azure.com) et cliquez sur Microsoft Entra ID." - }, - "appRegistrations": { - "title": "Aller aux Enregistrements d'application", - "body": "Dans le menu de gauche, cliquez sur Enregistrements d'application." - }, - "registerApp": { - "title": "Enregistrer une nouvelle application", - "body": "Cliquez sur Nouvel enregistrement. Nommez-la UTMStack Graph Dev, sélectionnez Comptes de ce seul annuaire d'organisation (monolocataire) et cliquez sur Enregistrer." - }, - "clientSecret": { - "title": "Créer un secret client", - "body": "Allez dans Certificats et secrets → Nouveau secret client. Ajoutez une description, définissez l'expiration sur 730 jours (24 mois) et cliquez sur Ajouter.", - "copyNote": "Copiez la valeur du secret immédiatement — elle n'est affichée qu'une seule fois et ne pourra pas être récupérée ensuite." - }, - "apiPermissions": { - "title": "Ajouter les permissions Microsoft Graph", - "body": "Allez dans Permissions de l'API → Ajouter une permission et sélectionnez Microsoft Graph, puis choisissez Permissions d'application." - }, - "graphPermissions": { - "title": "Ajouter les quatre permissions Graph", - "body": "Ajoutez SecurityEvents.Read.All, Directory.Read.All, AuditLog.Read.All et IdentityRiskEvent.Read.All." - }, - "adminConsent": { - "title": "Accorder le consentement administrateur", - "body": "De retour dans Permissions de l'API, cliquez sur Accorder le consentement administrateur pour {tenant} et confirmez." - }, - "noteIds": { - "title": "Copier les ID de l'application", - "body": "Allez dans la Vue d'ensemble de l'application et copiez l'ID d'application (client) et l'ID d'annuaire (tenant). Vous avez également besoin de la valeur du secret copiée à l'étape 4." - } - }, - "credentialsSection": "Identifiants", - "credentials": { - "title": "Connecter votre tenant Microsoft 365", - "body": "Saisissez les informations des étapes ci-dessus. UTMStack vérifie les identifiants avant l'enregistrement. Vous pouvez ajouter plusieurs groupes de configuration." - }, - "fields": { - "tenantId": { - "label": "ID de tenant (ID d'annuaire)" - }, - "clientId": { - "label": "ID de client (ID d'application)" - }, - "clientSecret": { - "label": "Secret client" - }, - "cloudEnv": { - "label": "Environnement cloud (facultatif)", - "hint": "Commercial (par défaut), GCC, GCCHigh ou DoD" + "action": { + "INCIDENT_CREATED": "Incident créé", + "INCIDENT_ALERT_ADD": "Alertes ajoutées", + "INCIDENT_ALERT_STATUS_CHANGED": "Statut des alertes modifié", + "INCIDENT_STATUS_CHANGE": "Statut modifié", + "INCIDENT_NOTE_ADD": "Note ajoutée", + "INCIDENT_NOTE_CHANGE": "Note modifiée", + "INCIDENT_ASSIGNED": "Attribution modifiée" + }, + "create": { + "title": "Créer un incident", + "stepIndicator": "Étape {{current}} sur {{total}}", + "selectedCount": "{{count}} alertes sélectionnées", + "submit": "Créer", + "success": "Incident créé", + "error": "Impossible de créer l'incident", + "details": { + "nameLabel": "Nom", + "namePlaceholder": "Titre court et descriptif", + "descriptionLabel": "Description", + "descriptionPlaceholder": "Contexte, portée, notes initiales…" } - } } - }, - "cloud": { - "howItWorksTitle": "Comment ça marche", - "howItWorksBody": "{{name}} s'exécute entièrement dans UTMStack — pas d'agent ni de collecteur à déployer. Fournissez des identifiants API en lecture seule et UTMStack extraira les événements selon un horaire, les analysera et les ingérera dans Log Explorer.", - "connectionTitle": "Connexion", - "noFields": "Aucun champ de connexion configuré.", - "testConnection": "Tester la connexion", - "save": "Enregistrer", - "afterTitle": "Ce que vous verrez après la connexion", - "after1": "UTMStack effectue un remplissage initial des événements récents.", - "after2": "Ensuite, les événements sont extraits toutes les 1–5 minutes (dépend de l'API).", - "after3": "L'intégration apparaît sous Sources de données avec l'état d'extraction et le décalage actuels.", - "tenants": { - "title": "Groupes de configuration configurés", - "empty": "Aucun groupe de configuration pour le moment. Ajoutez le premier ci-dessous.", - "loading": "Chargement des groupes de configuration…", - "nameLabel": "Nom du groupe de configuration", - "namePlaceholder": "p. ex. acme-prod", - "add": "Ajouter un groupe de configuration", - "update": "Mettre à jour le groupe de configuration", - "delete": "Supprimer", - "edit": "Modifier", - "cancel": "Annuler", - "editing": "Édition : {{name}}", - "selectFile": "Sélectionner un fichier", - "replaceFile": "Remplacer le fichier", - "fileLoaded": "Fichier chargé", - "invalidJson": "Impossible de lire le fichier comme JSON.", - "createError": "Impossible de créer le groupe de configuration. Veuillez réessayer.", - "updateError": "Impossible de mettre à jour le groupe de configuration. Veuillez réessayer.", - "createSuccess": "Groupe de configuration créé avec succès.", - "updateSuccess": "Groupe de configuration mis à jour avec succès." - }, - "google": { - "sections": { - "createTopic": { - "title": "1 · Créer un sujet Pub/Sub", - "body": "Dans la console Google Cloud, ouvrez Pub/Sub → Sujets et créez un nouveau sujet. UTMStack recevra les événements via ce sujet.", - "docLabel": "Ouvrir la page des topics Pub/Sub" - }, - "createSubscription": { - "title": "2 · Créer un abonnement", - "body": "Dans le sujet, créez un abonnement de type Pull. UTMStack récupère les messages depuis cet abonnement." - }, - "configureSubscription": { - "title": "3 · Configurer l'abonnement", - "body": "Réglez la durée de conservation des messages sur une valeur correspondant à votre tolérance aux interruptions (7 jours par défaut convient). Laissez le délai d'acquittement à 10 secondes et l'expiration sur « Ne jamais expirer »." - }, - "logsRouter": { - "title": "4 · Ouvrir le routeur de logs", - "body": "Allez dans Logging → Routeur de logs et créez un nouveau sink. C'est ce qui transfère les logs de votre projet vers le sujet Pub/Sub créé ci-dessus." - }, - "sinkDestination": { - "title": "5 · Pointer le sink vers le sujet", - "body": "Choisissez Sujet Cloud Pub/Sub comme destination du sink et sélectionnez le sujet créé. Utilisez les filtres d'inclusion/exclusion pour limiter ce qui est transféré." - }, - "serviceAccount": { - "title": "6 · Créer un compte de service", - "body": "Ouvrez IAM et administration → Comptes de service et créez un nouveau compte de service. Attribuez-lui le rôle Éditeur Pub/Sub pour qu'UTMStack puisse lire l'abonnement.", - "docLabel": "Ouvrir la page des comptes de service" - }, - "serviceAccountKey": { - "title": "7 · Générer une clé pour le compte de service", - "body": "Ouvrez le compte de service, allez dans l'onglet Clés et ajoutez une nouvelle clé. Choisissez JSON comme type de clé." - }, - "downloadKey": { - "title": "8 · Télécharger et charger la clé JSON", - "body": "Enregistrez le fichier JSON téléchargé par Google : son contenu va dans le champ « Clé JSON du compte de service » ci-dessous." - } - }, - "fields": { - "projectId": { - "label": "ID de projet" - }, - "subscription": { - "label": "Nom de l'abonnement" - }, - "jsonKey": { - "label": "Clé JSON du compte de service" - } - }, - "intro": { - "title": "Fonctionnement", - "body": "UTMStack lit l'activité d'audit directement depuis Google Cloud via Pub/Sub. Un sink du Logs Router diffuse les journaux de votre projet dans un topic Pub/Sub ; UTMStack exécute un collecteur interne qui lit un abonnement Pull sur ce topic à l'aide d'une clé de compte de service. Rien n'est installé dans votre projet GCP.", - "diagram": { - "source": "Cloud Logging", - "edge1": "Logs Router", - "pubsub": "Pub/Sub", - "pubsubSub": "topic + abonnement", - "edge2": "collecte", - "utmstackSub": "alertes & corrélation" - }, - "note": "Aucun agent ne s'exécute dans GCP — UTMStack collecte les messages de l'abonnement Pub/Sub à l'aide de la clé JSON du compte de service que vous fournissez ci-dessous." - }, - "credentials": { - "title": "Configuration Pub/Sub", - "body": "Utilisez les valeurs collectées ci-dessus pour configurer UTMStack. Vous pouvez surveiller plusieurs projets en enregistrant des configurations supplémentaires.", - "mapping": { - "intro": "Référence des champs", - "projectId": "Project ID — le projet GCP qui contient votre topic, votre abonnement et votre sink", - "subscription": "Nom de l'abonnement — l'abonnement Pull créé à l'étape 2", - "jsonKey": "Clé JSON du compte de service — le fichier téléchargé à l'étape 8" - } - } + }, + "alertingRules": { + "title": "Règles d’alerte", + "subtitle": "Règles de corrélation qui transforment les événements en alertes. Activez, ajustez ou créez les vôtres.", + "new": "Nouvelle règle", + "refresh": "Actualiser", + "empty": "Aucune règle correspondante.", + "loadError": "Impossible de charger les règles.", + "retry": "Réessayer", + "deleteConfirm": "Supprimer la règle « {{name}} » ?", + "adversary": { + "origin": "Origine", + "target": "Cible" }, - "azure": { - "sections": { - "sharedAccessPolicy": { - "title": "2 · Ajouter une politique d'accès partagé", - "body": "Ouvrez l'Event Hub → Politiques d'accès partagé et créez une politique avec uniquement l'autorisation Listen." - }, - "connectionString": { - "title": "3 · Copier la chaîne de connexion principale", - "body": "Ouvrez la politique et copiez la chaîne de connexion principale. Elle ressemble à : Endpoint=sb://...;SharedAccessKeyName=...;SharedAccessKey=..." - }, - "consumerGroup": { - "title": "4 · Créer un consumer group dédié", - "body": "Ouvrez l'Event Hub → Consumer groups et créez-en un nouveau pour UTMStack. Ne réutilisez pas $Default — donnez à UTMStack son propre groupe pour éviter les conflits de checkpoints avec d'autres consommateurs.", - "warn": "Créez un groupe de consommateurs spécifiquement pour UTMStack. N'utilisez pas $Default ni aucun autre groupe déjà utilisé — réutiliser un groupe de consommateurs entre des consommateurs non liés peut entraîner des comportements inattendus et des pertes d'événements. Toutes les instances UTMStack doivent partager le même groupe de consommateurs afin de traiter les événements ensemble." - }, - "storageContainer": { - "title": "6 · Créer un conteneur dans le compte de stockage", - "body": "Dans le compte de stockage → Conteneurs, créez un nouveau conteneur. Notez le nom du conteneur et la chaîne de connexion du compte (Clés d'accès → Chaîne de connexion)." - }, - "eventGrid": { - "title": "7 · Enregistrer le fournisseur de ressources Event Grid", - "body": "Dans Abonnements → Fournisseurs de ressources, enregistrez Microsoft.EventGrid si ce n'est pas déjà fait. Cela permet à Azure de transférer les événements au niveau de l'abonnement vers votre Event Hub." - }, - "createEventHub": { - "title": "Créer un Event Hub", - "body": "Dans le portail Azure, créez un espace de noms Event Hubs et un Event Hub à l'intérieur. UTMStack lira les événements depuis ce hub.", - "docLabel": "Démarrage rapide : créer un hub d'événements via le portail Azure" - }, - "createStorageAccount": { - "title": "Créer un Storage Account", - "body": "UTMStack a besoin d'un Storage Account pour enregistrer sa position de lecture. Créez-en un dans la même région que l'Event Hub.", - "docLabel": "Démarrage rapide : créer un compte de stockage" - }, - "storageConnection": { - "title": "Copier la chaîne de connexion du Storage Account", - "body": "Récupérez la chaîne de connexion du Storage Account avec clé via : All services → Storage accounts → votre compte → Access keys. UTMStack l'utilise pour stocker les points de contrôle de l'Event Hub." - }, - "createEventSubscription": { - "title": "Créer un abonnement aux événements", - "body": "Dans le panneau Événements de l'abonnement, créez un nouvel événement en cliquant sur Events → Event Subscription." - }, - "configureEventSubscription": { - "title": "Diriger l'abonnement aux événements vers votre Event Hub", - "body": "Configurez l'abonnement aux événements pour envoyer les journaux vers l'Event Hub créé à l'étape 1." - } - }, - "fields": { - "eventHubConnection": { - "label": "Chaîne de connexion Event Hub" - }, - "consumerGroup": { - "label": "Consumer group" - }, - "storageContainer": { - "label": "Nom du conteneur de stockage" - }, - "storageConnection": { - "label": "Chaîne de connexion du compte de stockage" - } - }, - "intro": { - "title": "Fonctionnement", - "body": "UTMStack lit l'activité d'audit directement depuis un Azure Event Hub. Vous configurez votre abonnement Azure pour diffuser les événements dans un Event Hub ; UTMStack exécute un collecteur interne qui lit ce hub et enregistre sa progression dans un Storage Account. Rien n'est installé dans votre tenant Azure.", - "diagram": { - "source": "événements d'abonnement", - "edge1": "diffuse vers", - "eventHub": "Event Hub", - "eventHubSub": "flux d'événements", - "edge2": "collecte", - "utmstackSub": "alertes & corrélation" - }, - "note": "Aucun agent ne s'exécute dans Azure — UTMStack collecte les événements depuis l'Event Hub à l'aide des chaînes de connexion que vous fournissez ci-dessous." - }, - "sampleLabel": "Exemple de chaîne de connexion :", - "credentials": { - "title": "Configuration de l'Event Hub", - "body": "Utilisez les données collectées dans les étapes ci-dessus pour configurer UTMStack. Vous pouvez ajouter plusieurs Event Hubs en enregistrant des configurations supplémentaires.", - "mapping": { - "intro": "Référence des champs", - "eventHubConnection": "Chaîne de connexion Event Hub — valeur obtenue à l'étape 3", - "consumerGroup": "Groupe de consommateurs — valeur obtenue à l'étape 4", - "storageContainer": "Nom du conteneur de stockage — valeur obtenue à l'étape 6", - "storageConnection": "Chaîne de connexion du compte de stockage — valeur obtenue à l'étape 7" - } - } + "state": { + "active": "Active", + "inactive": "Inactive" }, - "aws": { - "fields": { - "accessKeyId": { - "label": "ID de clé d'accès AWS" - }, - "secretAccessKey": { - "label": "Clé d'accès secrète AWS" - }, - "region": { - "label": "Région AWS par défaut" - }, - "logGroupName": { - "label": "Nom du log group" - } - }, - "intro": { - "title": "Fonctionnement", - "body": "UTMStack lit l'activité d'audit directement depuis AWS CloudWatch Logs. CloudTrail capture les appels API et les événements de gestion sur votre compte AWS, les transmet à un groupe de journaux CloudWatch, et UTMStack interroge ce groupe pour ingérer et corréler les événements.", - "diagram": { - "source": "événements API", - "edge1": "CloudTrail", - "cloudwatchSub": "groupes de journaux", - "edge2": "interroge", - "utmstackSub": "alertes & corrélation" - }, - "note": "Aucun agent n'est installé sur AWS — UTMStack collecte les événements de journal à l'aide des informations d'identification IAM en lecture seule que vous fournissez ci-dessous." - }, - "iamSection": "Configurer l'utilisateur IAM", - "iam": { - "dashboard": { - "title": "Ouvrir le tableau de bord IAM", - "body": "Ouvrez la console AWS, accédez au tableau de bord IAM et sélectionnez Users." - }, - "addUser": { - "title": "Ajouter un utilisateur", - "body": "Cliquez sur Add user, saisissez un nom d'utilisateur descriptif et passez à l'étape suivante." - }, - "attachPolicy": { - "title": "Attacher la politique en lecture seule", - "body": "Sous Permissions, attachez la politique requise. Sélectionnez CloudWatchLogsReadOnlyAccess pour un accès CloudWatch en lecture seule." - }, - "createUser": { - "title": "Créer l'utilisateur", - "body": "Vérifiez la configuration et cliquez sur Create user pour provisionner le compte." - }, - "openUser": { - "title": "Ouvrir le nouvel utilisateur", - "body": "Ouvrez l'utilisateur nouvellement créé en cliquant sur son nom pour consulter les détails et gérer les informations d'identification." - }, - "securityTab": { - "title": "Accéder aux informations d'identification de sécurité", - "body": "Sélectionnez l'onglet Security credentials pour créer des clés d'accès programmatiques." - }, - "createKey": { - "title": "Créer une clé d'accès", - "body": "Cliquez sur Create access key et choisissez l'option pour une application s'exécutant en dehors d'AWS (accès programmatique)." - }, - "confirmKey": { - "title": "Confirmer la création", - "body": "Confirmez la création de la clé d'accès. AWS génèrera un Access Key ID et une Secret Access Key." - }, - "downloadKey": { - "title": "Enregistrer vos informations d'identification", - "body": "Téléchargez le fichier d'informations d'identification ou copiez l'Access Key ID et la Secret Access Key dans un emplacement sécurisé — la Secret Access Key n'est affichée qu'une seule fois." - } - }, - "credentials": { - "title": "Saisir les informations d'identification", - "body": "Collez l'Access Key ID et la Secret Access Key obtenus dans les étapes précédentes. UTMStack vérifie les informations d'identification auprès d'AWS avant de les enregistrer." - }, - "cloudwatchSection": "Configurer AWS CloudWatch", - "cloudwatch": { - "createGroup": { - "title": "Créer un groupe de journaux CloudWatch", - "body": "Ouvrez la console CloudWatch, choisissez Log management et cliquez sur Create log group." - }, - "nameGroup": { - "title": "Nommer le groupe de journaux et définir la rétention", - "body": "Saisissez le nom du groupe de journaux utmstack et définissez la rétention à 1 jour. Cliquez sur Create log group." - }, - "openTrail": { - "title": "Ouvrir CloudTrail et créer un journal de suivi", - "body": "Dans la console CloudTrail, cliquez sur Create trail pour commencer à configurer un nouveau journal de suivi." - }, - "configureTrail": { - "title": "Configurer la livraison, la validation et l'intégration CloudWatch", - "body": "Dans le formulaire de création CloudTrail, définissez les options suivantes :", - "items": [ - "Nom et portée du journal : saisissez un nom descriptif ; activez Apply trail to all accounts in my organization si vous avez besoin d'une collecte à l'échelle de l'organisation.", - "Destination S3 : choisissez Create new S3 bucket (ou sélectionnez un bucket existant) pour la livraison des journaux bruts.", - "Chiffrement : activez Log file SSE-KMS et sélectionnez la clé KMS appropriée.", - "Validation des fichiers journaux : activez-la pour garantir l'intégrité des journaux livrés (recommandé).", - "CloudWatch Logs : activez la livraison vers CloudWatch, sélectionnez Use existing log group et saisissez le nom exact utmstack.", - "Rôle IAM : fournissez ou créez le rôle que CloudTrail assumera pour écrire dans S3 et publier dans CloudWatch." - ] - }, - "eventTypes": { - "title": "Sélectionner les types d'événements", - "body": "Activez les catégories d'événements requises pour la surveillance et l'audit.", - "management": { - "label": "1 · Événements de gestion", - "body": "Activez Management events et sélectionnez All pour enregistrer toute l'activité API gérant les ressources AWS (création, mise à jour, suppression)." - }, - "data": { - "label": "2 · Événements de données", - "body": "Ajoutez un Data event. Choisissez S3 et sélectionnez Log all events pour capturer les opérations au niveau des objets, telles que GetObject et PutObject." - }, - "network": { - "label": "3 · Événements d'activité réseau", - "body": "Dans la section Network Activities, ajoutez au moins un service (ex. ec2.amazonaws.com) et activez Log all events." - } - }, - "review": { - "title": "Vérifier et créer le trail", - "body": "Sur l'écran Configure event aggregation, acceptez les valeurs par défaut (ou ajustez si nécessaire). Vérifiez tous les paramètres et cliquez sur Create trail." - } - } - }, - "crowdstrike": { - "intro": { - "title": "Fonctionnement", - "body": "UTMStack lit les détections et l'activité d'audit directement depuis l'API CrowdStrike Falcon Event Streams. Vous créez un client API dans Falcon avec la portée Event Streams ; UTMStack exécute un collecteur interne qui diffuse les événements en utilisant ces identifiants. Rien n'est installé sur vos endpoints ni dans Falcon.", - "diagram": { - "source": "détections & événements", - "edge1": "Event Streams API", - "api": "Falcon API", - "apiSub": "flux d'événements", - "edge2": "collecte", - "utmstackSub": "alertes & corrélation" - }, - "note": "UTMStack ne déploie aucun agent — il collecte les événements depuis Falcon en utilisant les identifiants du client API en lecture seule que vous fournissez ci-dessous." - }, - "sections": { - "apiClients": { - "title": "Ouvrir API Clients and Keys", - "body": "Dans la console Falcon, ouvrez le menu (icône hamburger, en haut à gauche) et accédez à Support and resources → API Clients and Keys." - }, - "createClient": { - "title": "Créer un nouveau client API", - "body": "Cliquez sur Create API Client pour démarrer la définition d'un nouveau client." - }, - "scopes": { - "title": "Nommer le client et accorder la portée Event Streams", - "body": "Donnez au client un nom descriptif (UTMStack l'utilise pour identifier la source d'événements) et sélectionnez les portées API requises pour Event Streams. Cliquez sur Create pour générer les identifiants." - }, - "recordCredentials": { - "title": "Enregistrer les identifiants", - "body": "Copiez le Client ID, le Client Secret et le Base URL correspondant à votre région CrowdStrike. Le secret n'est affiché qu'une seule fois — conservez-le en lieu sûr. Vous les collerez tous trois dans le formulaire ci-dessous." - } - }, - "credentials": { - "title": "Configuration du client API", - "body": "Utilisez les identifiants des étapes précédentes pour configurer UTMStack. Vous pouvez ajouter plusieurs clients CrowdStrike en enregistrant des configurations supplémentaires.", - "mapping": { - "intro": "Référence des champs", - "appName": "Nom de l'application — le nom descriptif du client défini à l'étape 3 (identifie la source d'événements)", - "clientId": "Client ID — valeur enregistrée à l'étape 4", - "clientSecret": "Client Secret — valeur enregistrée à l'étape 4 (affiché une seule fois)", - "cloudRegionUrl": "Base URL — le point de terminaison de votre région, ex. https://api.crowdstrike.com (us-1), https://api.us-2.crowdstrike.com (us-2), https://api.eu-1.crowdstrike.com (eu-1)" - } - }, - "fields": { - "appName": { - "label": "Nom de l'application" - }, - "clientId": { - "label": "Client ID" - }, - "clientSecret": { - "label": "Client Secret" - }, - "cloudRegionUrl": { - "label": "Base URL (région cloud)" - } - } - } - }, - "custom": { - "whenTitle": "Quand l'utiliser", - "whenBody": "Quand votre source n'est pas dans le catalogue. Transférez syslog ou JSON arbitraire à UTMStack et définissez un analyseur pour normaliser les champs.", - "endpointsTitle": "Points d'accès", - "syslogUdp": "Syslog (UDP)", - "syslogTls": "Syslog (TLS)", - "httpJson": "HTTP / JSON", - "payloadTitle": "Exemple de payload JSON", - "parserTitle": "Définir l'analyseur", - "parserBody": "Les événements entrants sont stockés sous le type de données {{dataType}}. Ajoutez un filtre d'analyse afin que la charge utile brute soit mappée en champs structurés, puis créez des règles d'alerte par-dessus.", - "openEditor": "Ouvrir l'éditeur d'analyseur", - "powershellLabel": "PowerShell (Exécuter en tant qu'administrateur)", - "linuxLabel": "Linux — bash", - "macosLabel": "macOS — bash", - "exampleLabel": "Exemple de cible syslog sur {{name}} :", - "intro": { - "title": "Fonctionnement", - "body": "Une intégration personnalisée ingère des journaux depuis toute source non couverte par les modules intégrés. Vous installez le UTMStack Collector, enregistrez un écouteur pour vos données avec le protocole de votre choix, puis pointez votre source vers celui-ci.", - "note": "Choisissez ci-dessous le protocole que votre source peut envoyer (syslog UDP/TCP/TLS, ou HTTP/HTTPS pour JSON) — le Collector crée le type de données automatiquement." - }, - "diagram": { - "source": "Votre source", - "sourceSub": "toute application ou appareil", - "forwarder": "Collector", - "ingests": "ingère", - "utmstackSub": "alertes & corrélation" - }, - "choose": { - "title": "Choisir le protocole et le port", - "body": "Sélectionnez la façon dont votre source envoie les données et le port sur lequel le Collector doit écouter, puis exécutez la commande d'activation sur l'hôte Collector.", - "portLabel": "Port d'écoute", - "tlsFirst": "Chargez d'abord votre certificat TLS et votre clé sur le Collector :", - "enableLabel": "Activez ensuite l'intégration :", - "authNote": "Pour exiger une authentification, ajoutez --auth bearer (jeton) ou --auth hmac — le Collector affiche un jeton à utiliser dans l'en-tête Authorization." - }, - "send": { - "title": "Pointer votre source vers le Collector", - "bodyNetwork": "Configurez votre source pour envoyer les journaux syslog {{proto}} vers {{host}}:{{port}}. La plupart des appareils disposent d'un paramètre syslog distant ou de transfert de journaux à cet effet.", - "bodyHttp": "Envoyez vos événements au format JSON via HTTP POST vers {{endpoint}}. Chaque corps de requête est un événement JSON :", - "httpBindNote": "L'écouteur HTTP/HTTPS est lié à 127.0.0.1 (l'hôte Collector) par défaut ; envoyez donc les requêtes depuis une application s'exécutant sur cet hôte, ou placez un proxy inverse devant. Pour les sources distantes, utilisez syslog (UDP/TCP/TLS)." - }, - "manualCommand": { - "title": "Optional — Enable via the command line instead", - "intro": "Prefer the terminal? SSH into the Collector host and run the command below — it matches whatever protocol and port you have selected above." + "owner": { + "system": "Système", + "custom": "Personnalisée" + }, + "toolbar": { + "search": "Rechercher des règles…", + "allCategories": "Toutes les catégories", + "allAdversaries": "Tous les adversaires", + "allStates": "Tous les états", + "allOwners": "Toutes les origines", + "allDataTypes": "Tous les types" + }, + "table": { + "name": "Règle", + "category": "Catégorie", + "technique": "Technique", + "adversary": "Adversaire", + "impact": "Impact", + "active": "Active", + "dataTypes": "Types de données", + "selectAll": "Tout sélectionner", + "selectRow": "Sélectionner {{name}}" + }, + "export": { + "all": "Tout exporter", + "selected": "Exporter ({{count}})", + "error": "Impossible d’exporter les règles" + }, + "view": { + "description": "Description", + "details": "Détails", + "impact": "Impact (C·I·D)", + "dataTypes": "Types de données", + "updated": "Mise à jour", + "relPath": "Chemin", + "definition": "Condition (CEL)", + "correlationSteps": "Étapes de corrélation", + "correlation": "Corrélation", + "groupBy": "Grouper par", + "deduplicateBy": "Dédupliquer par", + "references": "Références" + }, + "editor": { + "createTitle": "Nouvelle règle", + "edit": "Modifier", + "delete": "Supprimer", + "export": "Exporter", + "cancel": "Annuler", + "save": "Enregistrer", + "metadata": "Métadonnées", + "name": "Nom", + "confidentiality": "Confidentialité", + "integrity": "Intégrité", + "availability": "Disponibilité", + "dataTypes": "Types de données", + "dataTypesHint": "séparés par des virgules", + "activeOnSave": "Active", + "definitionSection": "Définition", + "where": "Condition (CEL)", + "whereHint": "Expression CEL évaluée par événement", + "correlationSteps": "Étapes de corrélation", + "correlationStepsHint": "tableau JSON", + "jsonArray": "tableau JSON", + "nameRequired": "Le nom est requis", + "definitionRequired": "La condition est requise", + "invalidJson": "Un champ de la définition contient du JSON invalide", + "addStep": "Ajouter une étape de corrélation", + "step": "Étape {{n}}", + "removeStep": "Supprimer l’étape", + "indexPattern": "Modèle d’index", + "within": "Fenêtre", + "count": "Nombre", + "conditions": "Conditions", + "field": "Champ", + "value": "Valeur", + "addCondition": "Ajouter une condition", + "orGroup": "Groupe Or {{n}}", + "addOr": "Ajouter un groupe Or", + "removeOr": "Supprimer", + "fieldsHint": "noms de champs", + "referencesHint": "URLs", + "visual": "Visuel", + "code": "Code", + "dataTypesPick": "Sélectionner…", + "dataTypesSearch": "Rechercher des types…", + "dataTypesNone": "Aucun type de données", + "visualTab": "Visuel", + "codeTab": "Code", + "yamlError": "Impossible d'appliquer le YAML : {{error}}", + "test": "Test" + }, + "toast": { + "activated": "Règle activée", + "deactivated": "Règle désactivée", + "toggleError": "Impossible de changer l’état de la règle", + "deleted": "Règle supprimée", + "deleteError": "Impossible de supprimer la règle", + "created": "Règle créée", + "saved": "Règle enregistrée", + "saveError": "Impossible d’enregistrer la règle" + }, + "operator": { + "filter_term": "égal (term)", + "must_not_term": "différent (term)", + "filter_match": "correspond (texte)", + "must_not_match": "ne correspond pas (texte)" + }, + "where": { + "matchPrefix": "Correspond à", + "all": "toutes", + "any": "au moins une", + "matchSuffix": "de ces conditions :", + "negate": "Nier", + "listHint": "séparés par des virgules", + "advanced": "Cette condition utilise du CEL avancé — modifiez-la en Code ou reconstruisez-la visuellement.", + "and": "ET", + "or": "OU" + }, + "celOp": { + "exists": "existe", + "equals": "égal à", + "equalsIgnoreCase": "égal (sans casse)", + "contains": "contient", + "oneOf": "est l’un de", + "containsAll": "contient tous", + "startsWith": "commence par", + "endsWith": "finit par", + "regexMatch": "regex", + "lessThan": "<", + "lessOrEqual": "≤", + "greaterThan": ">", + "greaterOrEqual": "≥", + "inCIDR": "dans CIDR", + "isHour": "l’heure est", + "isMinute": "la minute est", + "isDayOfWeek": "le jour est", + "isWeekend": "est le week-end", + "isWorkDay": "est un jour ouvré", + "isBetweenTime": "heure entre" + }, + "import": { + "button": "Importer", + "error": "Échec de l'importation", + "resultTitle": "Résultats de l'import", + "approved": "Approuvés", + "rejected": "Rejetés", + "done": "Terminé" + }, + "test": "Test" + }, + "regexPatterns": { + "title": "Expressions régulières", + "subtitle": "Expressions régulières réutilisables référencées par les filtres d'analyse.", + "new": "Nouveau motif", + "search": "Rechercher des motifs…", + "refresh": "Actualiser", + "view": "Voir", + "system": "Système", + "user": "Personnalisé", + "loading": "Chargement des motifs…", + "loadError": "Impossible de charger les motifs.", + "retry": "Réessayer", + "empty": "Aucun motif ne correspond à cette vue.", + "tabs": { + "all": "Tous", + "system": "Système", + "user": "Personnalisés" + }, + "cols": { + "pattern": "Motif", + "definition": "Définition", + "type": "Type" + }, + "editor": { + "titleNew": "Nouveau motif", + "patternId": "ID du motif", + "patternIdHint": "Nom unique référencé depuis les filtres.", + "description": "Description", + "descriptionPlaceholder": "Ce que ce motif reconnaît (facultatif)", + "definition": "Définition (regex)", + "definitionHint": "Une expression régulière. Peut référencer d'autres motifs.", + "readOnly": "Motif système — en lecture seule.", + "save": "Enregistrer", + "saving": "Enregistrement…", + "delete": "Supprimer", + "confirmDelete": "Confirmer la suppression", + "cancel": "Annuler" + }, + "toast": { + "saved": "Motif enregistré", + "saveError": "Échec de l'enregistrement du motif", + "deleted": "Motif supprimé", + "deleteError": "Échec de la suppression du motif", + "patternIdRequired": "L'ID du motif est requis", + "definitionRequired": "La définition est requise" } - }, - "remoteEnable": { - "title": "Activer cette intégration à distance", - "body": "Choisissez un Collector, sélectionnez le protocole et le port, puis activez l'intégration — aucun SSH requis.", - "noPermission": "Vous n'avez pas la permission de gérer les intégrations distantes. Demandez à un administrateur d'accorder la permission integrations.write.", - "loadingCollectors": "Chargement des Collectors…", - "noCollectors": "Aucun Collector n'est enregistré pour le moment. Installez-en un ci-dessus pour activer les intégrations à distance.", - "forwarderOffline": "Ce Collector est hors ligne et ne peut pas recevoir de modifications de configuration en ce moment.", - "legendOnline": "{{count}} en ligne", - "legendOffline": "{{count}} hors ligne", - "legendTotal": "{{count}} total", - "forwarderLabel": "Collector", - "protoLabel": "Protocole", - "portLabel": "Port", - "currentStateLoading": "Vérification de la configuration actuelle…", - "currentlyEnabled": "Actuellement : activé · {{proto}} · port {{port}}", - "currentlyDisabled": "Actuellement : désactivé · {{proto}} · port {{port}}", - "authLabel": "Authentification", - "authNone": "Aucune", - "authBearer": "Jeton Bearer", - "authHmac": "Signature HMAC", - "pathLabel": "Chemin", - "signatureHeaderLabel": "En-tête de signature", - "certTitle": "Certificat TLS", - "certLoading": "Vérification du statut du certificat…", - "certLoaded": "Un certificat valide est déjà chargé sur ce Collector.", - "certMissing": "Aucun certificat chargé pour le moment — téléchargez-en un pour activer ce protocole.", - "certInvalid": "Le certificat chargé est invalide : {{error}}", - "certPemLabel": "Certificat", - "keyPemLabel": "Clé privée", - "caPemLabel": "Certificat CA", - "uploadCertsButton": "Télécharger le certificat", - "certUploadSuccess": "Certificat téléchargé.", - "certUploadError": "Échec du téléchargement du certificat.", - "certReadError": "Impossible de lire le(s) fichier(s) sélectionné(s).", - "enableButton": "Activer l'intégration", - "disableButton": "Désactiver l'intégration", - "enableSuccess": "Intégration activée.", - "disableSuccess": "Intégration désactivée.", - "enableError": "Échec de la mise à jour de l'intégration.", - "secretWarning": "Stockez ce jeton en toute sécurité — il ne sera pas affiché à nouveau.", - "sendToInstance": "Envoyer à l'instance", - "enterpriseFeature": "Ceci est une fonctionnalité Enterprise.", - "addCollector": "Ajouter un Collector", - "addApiKey": "Ajouter une clé API", - "apiKeyLabel": "Clé API", - "apiKeyHint": "Vous aurez d'abord besoin d'une clé API.", - "apiKeyPlaceholder": "Sélectionner une clé API", - "apiKeyAddNew": "Ajouter une clé API…", - "apiKeyNone": "Aucune clé API pour l'instant", - "forwarderNoRemoteControl": "Ce forwarder a été installé avec le contrôle à distance désactivé. Il ignore la configuration envoyée d'ici, et cela ne peut être modifié que sur la machine elle-même." - } - }, - "codeBlock": { - "copy": "Copier", - "copied": "Copié" - }, - "createDrawer": { - "title": "Nouvelle intégration personnalisée", - "moduleName": "Nom du module", - "moduleNameHint": "Identificateur unique. Sans espaces.", - "moduleNamePlaceholder": "ma-app-personnalisee", - "prettyName": "Nom d'affichage", - "prettyNamePlaceholder": "Ma App Personnalisée", - "dataType": "Type de données", - "dataTypePlaceholder": "Identificateur unique pour ce type de données", - "icon": "Icône", - "iconHint": "PNG, SVG, JPEG, GIF ou WEBP. Maximum 3 MB. Utilisé comme logo d'intégration.", - "iconPreview": "Aperçu de l'icône", - "dataTypeExists": "Ce type de données existe déjà", - "invalidFileType": "L'icône doit être un fichier image valide (PNG, JPEG, SVG, GIF, WEBP)", - "fileTooLarge": "L'icône ne doit pas dépasser 3 MB", - "fileReadError": "Échec de la lecture du fichier", - "cancel": "Annuler", - "create": "Créer l'intégration", - "creating": "Création…", - "editTitle": "Modifier l'intégration", - "save": "Enregistrer", - "saving": "Enregistrement…", - "currentIcon": "Icône actuelle — importez un fichier pour la remplacer", - "name": "Nom de l'intégration", - "namePlaceholder": "ex. Acme Firewall", - "description": "Description", - "descriptionPlaceholder": "Ce que cette intégration ingère et pourquoi (facultatif)", - "identifierHint": "Stocké sous “{{id}}” (dérivé du nom)", - "nameTaken": "Ce nom d'intégration ne peut pas être utilisé — une intégration avec cet identifiant existe déjà.", - "removeIcon": "Supprimer l'icône", - "defaultIconNote": "Icône par défaut — importez un fichier pour utiliser la vôtre." - }, - "toast": { - "created": "Intégration créée", - "updated": "Intégration mise à jour", - "updateError": "Échec de la mise à jour de l'intégration" - }, - "delete": { - "title": "Supprimer l'intégration", - "confirm": "Supprimer cette intégration ?", - "yes": "Supprimer", - "no": "Annuler", - "deleted": "Intégration supprimée", - "error": "Échec de la suppression de l'intégration" }, - "modules": { - "WINDOWS_AGENT": "Collectez l'activité système, sécurité et journaux d'événements Windows via l'agent léger UTMStack installé sur chaque hôte.", - "LINUX_AGENT": "Collectez les journaux système, d'authentification et d'audit Linux via l'agent léger UTMStack installé sur chaque hôte.", - "MACOS": "Collectez l'activité des journaux système et sécurité macOS depuis les endpoints Apple Mac via l'agent léger UTMStack.", - "VMWARE": "Ingérez le syslog de l'hyperviseur VMware ESXi afin que l'activité et les événements des hôtes de virtualisation soient surveillés dans UTMStack.", - "NETFLOW": "Ingérez les enregistrements NetFlow provenant des routeurs et commutateurs pour surveiller les schémas de trafic réseau et détecter les anomalies.", - "AWS_IAM_USER": "Ingérez l'activité des comptes AWS et les appels API via CloudTrail et CloudWatch pour auditer l'utilisation, les accès et les modifications dans le cloud.", - "AZURE": "Ingérez les journaux de plateforme et d'activité Microsoft Azure pour surveiller les charges de travail cloud, les identités et les modifications de ressources.", - "O365": "Ingérez les journaux d'audit Microsoft 365 couvrant Exchange, Teams, SharePoint et OneDrive pour surveiller l'activité des utilisateurs et des administrateurs.", - "O365_GRAPH": "Ingeste les événements de sécurité Microsoft Graph — alertes, incidents, audit du répertoire, sign-ins, détections de risque et journaux Purview — pour surveiller l'identité et les menaces dans votre tenant.", - "GCP": "Ingérez les journaux d'audit et d'activité Google Cloud Platform pour surveiller le calcul, le stockage et les identités dans vos projets.", - "KASPERSKY": "Ingérez les détections et la télémétrie des endpoints Kaspersky Security Center pour corréler l'activité des logiciels malveillants sur le réseau.", - "ESET": "Ingérez les détections et la télémétrie des endpoints ESET PROTECT pour corréler la défense multicouche contre les logiciels malveillants sur votre parc.", - "BITDEFENDER": "Ingérez les détections et la télémétrie des endpoints Bitdefender GravityZone pour corréler les menaces sur les appareils professionnels.", - "SENTINEL_ONE": "Ingérez les détections et la télémétrie comportementale des endpoints SentinelOne pour corréler et investiguer les menaces à grande échelle.", - "SOPHOS": "Ingérez les détections Sophos Central couvrant les endpoints, serveurs, pare-feu et messagerie pour corréler les menaces en un seul endroit.", - "CROWDSTRIKE": "Ingérez les détections CrowdStrike Falcon des endpoints et des charges de travail pour corréler l'activité des menaces cloud-native dans UTMStack.", - "CISCO": "Ingérez les journaux de trafic, VPN et menaces du pare-feu Cisco ASA pour surveiller la sécurité périmétrique et les accès dans UTMStack.", - "MERAKI": "Ingérez le syslog des pare-feu et appliances de sécurité Cisco Meraki pour surveiller le trafic réseau géré dans le cloud et les menaces.", - "FIRE_POWER": "Ingérez les journaux Cisco Firepower NGFW et IPS pour surveiller les tentatives d'intrusion et l'activité des menaces en périmètre.", - "CISCO_SWITCH": "Ingérez le syslog et la télémétrie des commutateurs Cisco pour surveiller les performances réseau, les modifications de configuration et la sécurité.", - "FORTIGATE": "Ingérez les journaux de trafic et de menaces Fortinet FortiGate NGFW pour surveiller la sécurité périmétrique et l'activité réseau.", - "FORTIWEB": "Ingérez les journaux Fortinet FortiWeb WAF pour surveiller les attaques contre les applications web et protéger les services et API exposés.", - "SOPHOS_XG": "Ingérez les journaux du pare-feu Sophos XG couvrant le filtrage web, l'IPS et le VPN pour surveiller le trafic réseau et les menaces.", - "PALO_ALTO": "Ingérez les journaux de trafic et de menaces Palo Alto Networks NGFW pour surveiller l'utilisation des applications et la sécurité périmétrique.", - "SONIC_WALL": "Ingérez les journaux de trafic et de menaces SonicWall NGFW pour surveiller la sécurité périmétrique et l'activité réseau dans UTMStack.", - "PFSENSE": "Ingérez les journaux de pare-feu et de routeur pfSense avec la gestion unifiée des menaces pour surveiller le trafic réseau et les menaces.", - "MIKROTIK": "Ingérez les journaux de pare-feu, de routage et sans fil MikroTik RouterOS pour surveiller l'activité réseau et la configuration.", - "AIX": "Collectez les journaux système, sécurité et d'audit IBM AIX Unix pour surveiller l'activité sur les plateformes IBM Power dans UTMStack.", - "AS_400": "Collectez les journaux système et d'audit IBM AS/400 (IBM i) pour surveiller l'activité des utilisateurs sur les plateformes midrange OS/400.", - "ORACLE": "Ingérez les journaux d'audit Oracle Database pour surveiller les requêtes, les accès et les activités privilégiées sur vos bases de données.", - "SURICATA": "Ingérez les alertes et événements réseau Suricata IDS/IPS pour détecter les intrusions et le trafic malveillant sur le réseau.", - "DECEPTIVE_BYTES": "Ingérez les alertes Deceptive Bytes depuis sa plateforme active de tromperie des endpoints pour détecter rapidement l'activité des attaquants.", - "GITHUB": "Ingérez les journaux d'audit GitHub pour surveiller les accès aux dépôts, les modifications de code et l'activité de l'organisation pour la sécurité des sources.", - "UTMSTACK": "Ingérez la télémétrie SIEM et XDR propre à UTMStack pour surveiller la santé de la plateforme, l'activité interne et les événements d'auto-audit.", - "NGINX": { - "name": "Nginx", - "description": "Ingérez les journaux d'accès et d'erreur de Nginx pour surveiller l'activité du serveur web, le trafic du proxy inverse et les requêtes des clients." - }, - "APACHE": { - "name": "Apache", - "description": "Ingérez les journaux d'accès et d'erreur d'Apache HTTPD pour surveiller l'activité du serveur web et les requêtes des clients." - }, - "APACHE2": { - "name": "Apache2", - "description": "Ingérez les journaux du serveur web Apache2 (HTTPD) pour surveiller le traitement des requêtes, les erreurs et l'accès sur les hôtes Linux." - }, - "IIS": { - "name": "IIS", - "description": "Ingérez l'activité d'accès et les fichiers journaux d'Internet Information Services (IIS) pour surveiller le service web Windows." - }, - "MYSQL": { - "name": "MySQL", - "description": "Ingérez l'activité des journaux MySQL pour surveiller les requêtes, l'authentification et l'accès au magasin de données." - }, - "POSTGRESQL": { - "name": "PostgreSQL", - "description": "Ingérez les journaux PostgreSQL pour surveiller les requêtes, l'accès et l'activité de vos magasins de données." - }, - "MONGODB": { - "name": "MongoDB", - "description": "Ingérez l'activité des journaux MongoDB pour surveiller l'accès à la base de données documentaire, les requêtes et le comportement de l'application." - }, - "REDIS": { - "name": "Redis", - "description": "Ingérez l'activité des journaux et de la télémétrie Redis pour surveiller l'utilisation du magasin de données en mémoire et les charges de travail en temps réel." - }, - "ELASTICSEARCH": { - "name": "Elasticsearch", - "description": "Ingérez les journaux Elasticsearch pour surveiller le moteur de recherche et d'analyse et ses charges de travail applicatives." - }, - "LOGSTASH": { - "name": "Logstash", - "description": "Ingérez les journaux des pipelines Logstash pour surveiller le pipeline de traitement des données et ses transformations d'événements." - }, - "KIBANA": { - "name": "Kibana", - "description": "Ingérez les journaux Kibana pour surveiller la couche de visualisation et d'exploration des données et son utilisation." - }, - "KAFKA": { - "name": "Apache Kafka", - "description": "Ingérez les journaux Apache Kafka pour surveiller les pipelines de streaming en temps réel, les brokers et le flux de messages." - }, - "NATS": { - "name": "NATS", - "description": "Ingérez les journaux de messagerie NATS pour surveiller le bus de messages, la connectivité et la livraison des événements." - }, - "HAPROXY": { - "name": "HAProxy", - "description": "Ingérez les journaux HAProxy pour surveiller l'équilibrage de charge, le trafic du proxy et la disponibilité du réseau." - }, - "TRAEFIK": { - "name": "Traefik", - "description": "Ingérez les journaux Traefik pour surveiller le routage, l'équilibrage de charge et le trafic du proxy entre les charges de travail." - }, - "OSQUERY": { - "name": "osquery", - "description": "Ingérez les journaux OsQuery pour surveiller l'état des terminaux, les requêtes et l'inventaire du système via des requêtes au style SQL." - }, - "SYSLOG": { - "name": "Syslog", - "description": "Envoyez le syslog (RFC 5424/3164) de n'importe quel appareil ou application vers le point d'accès du collecteur pour une prise en charge centralisée des journaux." - }, - "JSON": { - "name": "JSON Input", - "description": "Envoyez des charges de journaux JSON vers le point d'ingestion pour une prise en charge structurée des événements d'applications et de scripts." - }, - "WINDOWS_SQL_SERVER": { - "name": "SQL Server Event Logs", - "description": "Collect Microsoft SQL Server audit and event records through the Windows Event Log and UTMStack agent." - }, - "WINDOWS_FILE_AUDITING": { - "name": "Windows File Access Auditing", - "description": "Collect Windows file access audit events through the Windows Event Log and UTMStack agent." - }, - "ELASTICsearch": { - "name": "ELASTICsearch", - "description": "Ingesta los registros de Elasticsearch para monitorear el motor de búsqueda y análisis y sus cargas de trabajo de aplicación." - } - }, - "edit": { - "title": "Modifier l'intégration" - }, - "allCategories": "Toutes les catégories", - "customOnly": "Personnalisé" - }, - "dataProcessing": { - "title": "Traitement des données", - "subtitle": "Statistiques d’ingestion et de traitement : événements reçus, rejetés par étape, et les principales sources et types.", - "ingestion": { - "title": "Ingestion", - "last24h": "dernières 24 heures", - "noData": "Aucune donnée sur cette fenêtre.", - "loadError": "Impossible de charger les statistiques d’ingestion.", - "groupBy": { - "dataSource": "Par source de données", - "dataType": "Par type de données" - }, - "status": { - "received": "Reçus", - "parsing_dropped": "Rejetés (analyse syntaxique)", - "analysis_dropped": "Rejetés (analyse)", - "correlation_dropped": "Rejetés (corrélation)", - "all": "Tous les événements" - } - }, - "filters": { - "title": "Filtres", - "new": "Nouveau filtre", - "search": "Rechercher par chemin…", - "refresh": "Actualiser", - "retry": "Réessayer", - "empty": "Aucun filtre ne correspond.", - "loadError": "Impossible de charger les filtres.", - "toggleError": "Impossible de changer l’état du filtre", - "system": "Système", - "custom": "Personnalisé", - "systemReadonly": "Les filtres système sont en lecture seule", - "view": "Voir", - "edit": "Modifier", - "ownership": { - "all": "Tous", + "parsingFilters": { + "title": "Pipelines", + "subtitle": "Pipelines YAML appliqués aux logs lors de leur analyse à l'ingestion.", + "new": "Nouveau pipeline", + "search": "Rechercher des pipelines…", + "refresh": "Actualiser", + "view": "Voir", "system": "Système", - "custom": "Personnalisés" - }, - "state": { - "all": "Tous", - "active": "Actifs", - "inactive": "Inactifs" - }, - "col": { - "filter": "Filtre", - "type": "Type", - "active": "Actif", - "actions": "Actions" - }, - "pageInfo": "{{from}}–{{to}} sur {{count}}" - }, - "editor": { - "createTitle": "Nouveau filtre", - "editTitle": "Modifier le filtre", - "viewTitle": "Voir le filtre", - "relPath": "Chemin", - "relPathHint": "Dossier + fichier, p. ex. syslog/mon-filtre.yaml", - "content": "Pipeline (YAML)", - "contentHint": "Les étapes s’exécutent dans l’ordre : grok, rename, delete, plugins dynamic, …", - "save": "Enregistrer", - "saving": "Enregistrement…", - "saved": "Filtre enregistré", - "saveError": "Impossible d’enregistrer le filtre", - "cancel": "Annuler", - "delete": "Supprimer", - "deleteConfirm": "Supprimer ce filtre ?", - "deleted": "Filtre supprimé", - "deleteError": "Impossible de supprimer le filtre" - }, - "kpi": { - "received": "Reçus", - "dropped": "Rejetés", - "dropRate": "{{rate}} % de rejet", - "stored": "Stockés", - "throughput": "Débit", - "perMin": "{{value}}/min", - "survival": "{{rate}}% conservés" - }, - "section": { - "overTime": "Événements dans le temps", - "top": "Top", - "dropReasons": "Motifs de rejet" - }, - "live": { - "auto": "Auto" - }, - "pipeline": { - "title": "Pipeline d’ingestion", - "stages": { - "received": "Reçus", - "parsed": "Analysés (parse)", - "analyzed": "Analysés", - "stored": "Stockés" - } - }, - "chart": { - "title": "Débit dans le temps", - "received": "Reçus", - "dropped": "Rejetés" - }, - "donut": { - "title": "Composition des rejets", - "dropped": "rejetés" - }, - "breakdown": { - "title": "Top sources et types", - "bars": "Barres", - "treemap": "Treemap", - "showAll": "Afficher les {{count}}", - "showLess": "Afficher moins", - "lastSeen": "Vu pour la dernière fois", - "ago": "il y a {{time}}" - } - }, - "datasources": { - "limitBanner": { - "title": "Limite de sources de données dépassée.", - "message": "Vous avez {{count}} sources de données mais votre licence en couvre {{limit}}. Les journaux des sources au-delà de la limite sont rejetés.", - "cta": "Gérer la licence", - "dismiss": "Ignorer" - }, - "title": "Sources de données", - "total": "{{count}} au total", - "subtitle": "Agents, intégrations et sources directes qui envoient des événements. Le statut est dérivé de la dernière fois que chaque source a été vue.", - "connectSource": "Connecter une source", - "loading": "Chargement des sources de données…", - "loadFailed": "Impossible de charger les sources de données.", - "retry": "Réessayer", - "none": "Aucune source ne correspond à cette vue.", - "ingestion": { - "title": "Ingestion", - "received": "événements reçus", - "none": "Aucune ingestion ces dernières 24 heures.", - "ago24h": "il y a 24h", - "now": "maintenant" - }, - "usage": { - "title": "Sources de données", - "ofUnlimited": "sur illimité", - "ofLimit": "sur {{limit}}", - "overLimit": "Au-delà de la limite sous licence — les données au-delà du plafond sont à risque.", - "configured": "configurées" - }, - "tabs": { - "all": "Toutes", - "agent": "Agents", - "puller": "Intégrations", - "direct": "Directes", - "offline": "Hors ligne" - }, - "toolbar": { - "searchPlaceholder": "Rechercher par nom…", - "list": "Liste", - "cards": "Cartes", - "refresh": "Actualiser" - }, - "labels": { - "filteredBy": "Filtré par label", - "add": "Ajouter un label…", - "addFirst": "Ajouter un label…", - "hint": "Saisissez un label et appuyez sur Entrée pour l'ajouter. Les modifications sont enregistrées automatiquement." - }, - "status": { - "live": "Actif", - "idle": "Inactif", - "offline": "Hors ligne" - }, - "kind": { - "agent": "Agent", - "puller": "Intégration", - "direct": "Directe" - }, - "cols": { - "source": "Source", - "type": "Type", - "status": "Statut", - "events24h": "Événements 24h", - "lastSeen": "Vu pour la dernière fois" - }, - "time": { - "justNow": "à l'instant", - "minutesAgo": "il y a {{count}}m", - "hoursAgo": "il y a {{count}}h", - "daysAgo": "il y a {{count}}j" + "user": "Personnalisé", + "loading": "Chargement des pipelines…", + "loadError": "Impossible de charger les pipelines.", + "retry": "Réessayer", + "empty": "Aucun pipeline ne correspond à cette vue.", + "tabs": { + "all": "Tous", + "active": "Actifs", + "inactive": "Inactifs", + "system": "Système", + "user": "Personnalisés" + }, + "cols": { + "filter": "Pipeline", + "type": "Type", + "active": "Actif", + "dataTypes": "Types de données", + "order": "Ordre", + "moveUp": "Monter", + "moveDown": "Descendre", + "actions": "Actions" + }, + "editor": { + "titleNew": "Nouveau pipeline", + "titleEdit": "Modifier le pipeline", + "titleSystem": "Pipeline (système)", + "name": "Nom", + "namePlaceholder": "Mon pipeline personnalisé", + "nameHint": "Sera enregistré sous {{file}}", + "namePending": "Choisissez un nom — il deviendra le nom du fichier.", + "content": "Contenu (YAML pipeline)", + "contentHint": "Une définition YAML pipeline: valide.", + "readOnly": "Pipeline système — en lecture seule. Vous pouvez seulement l'activer ou le désactiver.", + "save": "Enregistrer", + "saving": "Enregistrement…", + "delete": "Supprimer", + "confirmDelete": "Confirmer la suppression", + "cancel": "Annuler", + "test": "Test" + }, + "toast": { + "saved": "Pipeline enregistré", + "saveError": "Échec de l'enregistrement du pipeline", + "deleted": "Pipeline supprimé", + "deleteError": "Échec de la suppression du pipeline", + "activateError": "Échec du changement d'état du pipeline", + "nameRequired": "Le nom est requis", + "contentRequired": "Le contenu est requis", + "orderError": "Échec du changement d'ordre du pipeline" + }, + "visual": { + "visualTab": "Visuel", + "codeTab": "Code", + "codeOnly": "Passez au Code — ce contenu ne peut pas être affiché visuellement.", + "cantParse": "Impossible d'ouvrir l'éditeur visuel : {{error}}", + "dataTypes": "Types de données", + "steps": "Étapes", + "noSteps": "Aucune étape.", + "addStep": "Ajouter une étape :", + "removeStep": "Supprimer l'étape", + "moveUp": "Monter", + "moveDown": "Descendre", + "whereHint": "condition optionnelle (CEL)", + "addValue": "Ajouter une valeur", + "addPattern": "Ajouter un motif", + "rawHint": "Ce processeur s'édite en YAML brut.", + "rawNotMap": "Doit être un ensemble de champs clé : valeur.", + "dataTypesPick": "Choisir des types de données", + "dataTypesSearch": "Rechercher des types de données…", + "dataTypesNone": "Aucun type de données", + "dataTypesAdd": "Ajouter « {{value}} »", + "insertPattern": "Insérer un motif regex", + "patternSearch": "Rechercher des motifs…", + "patternNone": "Aucun motif", + "newPattern": "Nouveau motif…", + "createInsert": "Créer et insérer", + "patternCreated": "Motif « {{name}} » créé", + "patternCreateError": "Échec de la création du motif", + "patternIdInvalid": "L'ID du motif doit commencer par une lettre ou _ et n'utiliser que des lettres, chiffres ou _", + "patternDefRequired": "La définition est requise", + "parameters": "Paramètres", + "paramsKey": "Clé", + "paramsValue": "Valeur", + "entry": "Entrée {{n}}", + "order": "ordre {{n}}", + "orderLabel": "Ordre", + "removeEntry": "Supprimer l’entrée", + "addEntry": "Ajouter une entrée de pipeline", + "collapse": "Replier", + "expand": "Déplier", + "splitHint": "Vacío equivale a un espacio por defecto — en el YAML siempre aparece como fieldSplit: \" \"." + }, + "allDataTypes": "Tous les types de données", + "testPipeline": "Test pipeline" + }, + "soar": { + "title": "SOAR", + "subtitle": "Flux de réponse automatique : les conditions correspondent à une alerte, les commandes s'exécutent sur l'agent.", + "comingSoon": "Bientôt disponible", + "console": { + "loading": "Chargement des agents…", + "loadError": "Impossible de charger les agents.", + "pickAgent": "Sélectionner un agent", + "pickAgentHint": "Choisissez un agent dans la liste pour ouvrir sa console interactive.", + "lockedAgent": "Contrôle à distance désactivé" + }, + "search": "Rechercher des flux…", + "refresh": "Actualiser", + "new": "Nouveau flux", + "view": "Voir", + "system": "Système", + "loading": "Chargement des flux…", + "loadError": "Impossible de charger les flux.", + "retry": "Réessayer", + "empty": "Aucun flux ne correspond à cette vue.", + "templates": { + "title": "Nouveau flux", + "subtitle": "Choisis un modèle d'action ou pars de zéro.", + "loading": "Chargement des modèles…", + "loadError": "Impossible de charger les modèles.", + "empty": "Aucun modèle disponible.", + "cancel": "Annuler", + "scratch": "Partir de zéro" + }, + "tabs": { + "flows": "Flux", + "executions": "Historique d'exécutions", + "all": "Tous", + "active": "Actifs", + "inactive": "Inactifs", + "system": "Système", + "user": "Personnalisés" + }, + "cols": { + "flow": "Flux", + "platform": "Plateforme", + "conditions": "Conditions", + "commands": "Commandes", + "active": "Actif", + "lastRun": "Dernière exécution", + "failedRuns_one": "{{count}} exécution échouée", + "failedRuns_other": "{{count}} exécutions échouées" + }, + "operator": { + "IS": "est", + "IS_NOT": "n'est pas", + "CONTAINS": "contient", + "NOT_CONTAINS": "ne contient pas", + "EXISTS": "existe", + "NOT_EXISTS": "n'existe pas", + "START_WITH": "commence par", + "NOT_START_WITH": "ne commence pas par", + "ENDS_WITH": "se termine par", + "NOT_ENDS_WITH": "ne se termine pas par", + "IS_ONE_OF": "est l'un de", + "IS_NOT_ONE_OF": "n'est pas l'un de" + }, + "toast": { + "created": "Flux créé", + "saved": "Flux enregistré", + "saveError": "Échec de l'enregistrement du flux", + "deleted": "Flux supprimé", + "deleteError": "Échec de la suppression du flux", + "activateError": "Échec du changement d'état du flux" + }, + "editor": { + "createTitle": "Nouveau flux", + "visualTab": "Visuel", + "codeTab": "Code", + "name": "Nom", + "description": "Description", + "conditions": "Conditions", + "conditionsHint": "Le flux s'exécute quand une alerte remplit TOUTES ces conditions.", + "field": "champ", + "value": "valeur", + "valueList": "valeurs séparées par des virgules", + "addCondition": "Ajouter une condition", + "commands": "Commandes", + "commandsHint": "Exécutées dans l'ordre sur l'agent. Utilisez $(field.path) pour les valeurs de l'alerte et $[variables.NAME] pour les variables enregistrées.", + "addCommand": "Ajouter une commande", + "templatesButton": "Commandes courantes", + "templates": { + "isolate": "Isoler du réseau", + "shutdown": "Éteindre la machine", + "killProcess": "Tuer le processus", + "logout": "Déconnecter l'utilisateur", + "disableUser": "Désactiver l'utilisateur", + "blockIp": "Bloquer l'IP", + "restart": "Redémarrer la machine", + "uninstall": "Désinstaller l'application" + }, + "connector": { + "always": "toujours", + "success": "en cas de succès", + "failure": "en cas d'échec" + }, + "agentPlatform": "Plateforme de l'agent", + "shell": "Shell", + "shellAuto": "auto", + "whereToRun": "Où exécuter", + "run": { + "all": "Tous les agents", + "specific": "Un agent", + "except": "Tous sauf", + "allHint": "S'exécute sur tous les agents correspondant à cette plateforme." + }, + "selectAgentPlaceholder": "Sélectionner un agent…", + "excludedAgentsHint": "saisissez un nom d'hôte et appuyez sur Entrée", + "save": "Enregistrer", + "delete": "Supprimer", + "confirmDelete": "Confirmer la suppression", + "cancel": "Annuler", + "yamlError": "Impossible d'appliquer le YAML : {{error}}", + "nameRequired": "Le nom est requis", + "conditionsRequired": "Au moins une condition avec un champ est requise", + "commandsRequired": "Au moins une commande est requise", + "httpUrlInvalid": "Le nœud HTTP \"{{id}}\" a une URL invalide — elle doit être une URL http(s) valide.", + "httpBodyInvalid": "Le corps du nœud HTTP \"{{id}}\" n'est pas un JSON valide : {{error}}", + "incidentNameRequired": "Le nœud d'incident \"{{id}}\" nécessite un nom.", + "mailToRequired": "Le nœud d'e-mail \"{{id}}\" nécessite au moins un destinataire.", + "mailAddressInvalid": "Le nœud d'e-mail \"{{id}}\" contient une adresse {{field}} non valide : {{address}}.", + "mailSubjectRequired": "Le nœud d'e-mail \"{{id}}\" nécessite un objet.", + "identityModalTitle": "Détails du flux", + "platformRequired": "La plateforme de l'agent est requise", + "nameLabel": "Nom", + "namePlaceholder": "Nom du flux", + "descriptionLabel": "Description", + "descriptionHint": "Que fait ce flux ? (optionnel)", + "when": "Quand", + "whenTitle": "Une alerte remplit toutes ces conditions", + "on": "Sur", + "onTitle": "L'agent correspondant", + "thenRun": "Alors exécuter", + "thenTitle": "Ces commandes, dans l'ordre", + "selectField": "Choisir un champ…", + "selectPlatform": "Choisir une plateforme…", + "searchAgents": "Rechercher des agents…", + "noAgents": "Aucun agent", + "insertInto": "Insérer dans la commande {{n}} :", + "insertField": "Champ d'alerte", + "variables": "Variables", + "canvas": { + "node": "Nœud", + "deleteNode": "Supprimer le nœud", + "id": "ID", + "kind": "Type", + "executor": "Exécuteur", + "commandLabel": "Commande", + "paramsJson": "Paramètres (JSON)", + "dragToResize": "Glisser pour redimensionner", + "templatesLabel": "Modèles", + "templatesNeedPlatform": "Sélectionnez d'abord la plateforme cible", + "handlesHint": "Glissez depuis la poignée verte (en bas à gauche) pour on_success et depuis la rouge (en bas à droite) pour on_error. Plusieurs liens = parallèle. Plusieurs liens vers un même nœud = AND-join.", + "invalidJson": "JSON invalide", + "hidePalette": "Masquer la palette", + "hideInspector": "Masquer l'inspecteur", + "paletteLabel": "Palette", + "nodeShort": "Nœud", + "showPanel": "Afficher {{name}}", + "platform": "Plateforme", + "shell": "Shell", + "any": "toutes", + "auto": "auto", + "runOn": "Exécuter sur", + "runAutoTitle": "S'exécute sur l'hôte à l'origine de l'alerte", + "runSpecificTitle": "Épingler à un hôte (ou un modèle comme $(alert.foo))", + "runExceptTitle": "S'exécute sur l'hôte à l'origine de l'alerte, en excluant ceux de la liste", + "runAutoLabel": "source d'alerte", + "runSpecificLabel": "un hôte", + "runExceptLabel": "tous sauf", + "runAutoHint": "S'exécute sur $(alert.dataSource) — l'hôte à l'origine de l'alerte.", + "pickHost": "choisir un hôte…", + "orTemplateHint": "Ou saisissez un modèle — $(alert.field) est résolu à chaque exécution.", + "addExclusion": "ajouter une exclusion", + "searchAgents": "rechercher des agents…", + "noAgents": "aucun agent", + "insertField": "Insérer un champ", + "alert": "Alerte", + "wholeOutput": "sortie complète (éditez le chemin)", + "noAncestorsHint": "Aucun ancêtre d'enrichissement — ajoutez un nœud d'enrichissement en amont pour exposer sa sortie ici.", + "inserts": "insère", + "conditionalHint": "Toutes les conditions doivent correspondre. Correspondance → branche succès (verte) ; échec → branche erreur (rouge).", + "http": { + "url": "URL", + "urlInvalid": "URL http(s) invalide.", + "method": "Méthode", + "body": "Corps (JSON)", + "bodyInvalid": "JSON invalide", + "headers": "En-têtes HTTP", + "params": "Paramètres de requête", + "key": "Clé", + "value": "Valeur", + "addHeader": "Ajouter un en-tête", + "addParam": "Ajouter un paramètre" + }, + "incident": { + "name": "Nom de l'incident", + "namePlaceholder": "Ex. Connexion suspecte sur $(alert.dataSource)", + "description": "Description", + "descriptionPlaceholder": "Contexte facultatif pour les intervenants. Les gabarits comme $(alert.name) sont interpolés." + }, + "llm": { + "prompt": "Prompt", + "hint": "Le modèle est instruit de toujours répondre avec un seul objet JSON portant la propriété \"result\" ; le backend garantit ce format même si le modèle s'écarte. Les nœuds enfants s'y réfèrent via $({{nodeId}}.result) ou des champs spécifiques." + }, + "mail": { + "to": "À (séparés par une virgule)", + "cc": "CC (séparés par une virgule, facultatif)", + "addressInvalid": "Adresse e-mail non valide : {{address}}", + "subject": "Objet", + "subjectPlaceholder": "Ex. Alerte sur $(alert.dataSource)", + "body": "Corps", + "bodyPlaceholder": "Contenu du message. Les gabarits comme $(alert.name) sont interpolés." + }, + "notify": { + "level": "Level", + "message": "Message", + "messagePlaceholder": "Notification text. Templates like $(alert.name) are interpolated." + } + } + }, + "executions": { + "search": "Rechercher par ID d'alerte…", + "all": "Toutes", + "loading": "Chargement des exécutions…", + "loadError": "Impossible de charger les exécutions.", + "retry": "Réessayer", + "empty": "Aucune exécution pour l'instant.", + "cols": { + "status": "Statut", + "flow": "Flux", + "command": "Commande / Action", + "agent": "Agent", + "date": "Date", + "retries": "Tentatives", + "node": "Nœud" + }, + "filters": { + "source": "Source", + "allSources": "Toutes les sources" + }, + "manual": "Console interactive" + }, + "executionStatus": { + "WAITING": "En attente", + "PENDING": "En file d'attente", + "EXECUTING": "En cours d'exécution", + "EXECUTED": "Exécuté", + "FAILED": "Échoué", + "DEAD": "Inaccessible" + }, + "executionOrigin": { + "FLOW": "Flux", + "MANUAL": "Manuel" + }, + "nonExecutionCause": { + "AGENT_OFFLINE": "Agent hors ligne", + "AGENT_NOT_FOUND": "Agent introuvable", + "UNKNOWN": "Inconnu" + }, + "kpi": { + "flows": "Total des flux", + "active": "Actifs", + "runs24h": "Exécutions (24 h)", + "failed24h": "Échecs (24 h)" + }, + "neverRun": "jamais", + "create": { + "title": "Nouveau flux", + "modeManual": "Créer manuellement", + "modeAi": "Avec l'IA", + "aiLocked": "Activez SOC-AI et configurez-le pour utiliser ceci.", + "name": "Nom du flux", + "namePlaceholder": "p. ex. Bloquer l'IP en cas d'échecs répétés", + "aiDescriptionLabel": "Que doit faire ce flux ?", + "aiDescriptionPlaceholder": "p. ex. En cas d'alerte critique, rechercher l'IP source dans les menaces et la bloquer sur le pare-feu", + "aiCreate": "Créer avec l'IA", + "manualContinue": "Continuer" + } }, - "drawer": { - "loading": "Chargement…", - "loadFailed": "Impossible de charger la source de données.", - "statsIdentity": "Stats et identité", - "metadata": "Métadonnées", - "labelsSection": "Labels", - "dangerZone": "Zone de danger", - "rows": { - "events24h": "Événements 24h", - "lastSeen": "Vu pour la dernière fois", - "discovered": "Découverte", - "kind": "Type d'origine", - "dataType": "Type de donnée", - "ip": "IP", - "id": "ID" - }, - "dangerText": "La suppression retire cette source du registre. Les événements historiques restent consultables dans le Log Explorer ; si la source continue d'envoyer des données, elle sera redécouverte.", - "delete": "Supprimer la source", - "confirmDelete": "Confirmer la suppression", - "cancel": "Annuler", - "viewLogs": "Voir les journaux", - "trend": "Tendance d'ingestion", - "noTrend": "Aucun événement reçu sur cette période", - "logGap": "Dernier événement {{since}} — interruption possible des journaux" + "compliance": { + "title": "Compliance", + "subtitle": "Évaluez votre posture face aux frameworks de sécurité — voyez quels contrôles sont respectés et lesquels ne le sont pas.", + "comingSoon": "Bientôt disponible.", + "tabs": { + "frameworks": "Frameworks", + "schedule": "Planification", + "controls": "Contrôles" + }, + "search": "Rechercher des frameworks…", + "refresh": "Refresh", + "loading": "Chargement des frameworks…", + "loadError": "Could not load reports", + "retry": "Réessayer", + "empty": "Aucun framework ne correspond.", + "notEvaluated": "Non évalué", + "controlsCount": "{{n}} contrôles", + "enabledLabel": "Activé", + "runReport": "Exécuter le rapport", + "backToFrameworks": "Retour aux frameworks", + "statusAuto": "Auto (évalué)", + "overrideError": "Impossible de mettre à jour le statut", + "noteError": "Impossible d’enregistrer la note", + "notes": { + "title": "Notes", + "placeholder": "Ajouter une note…", + "save": "Enregistrer", + "cancel": "Annuler" + }, + "reasonModal": { + "title": "Motif requis", + "description": "Indiquez le motif du changement de statut. Il sera enregistré.", + "label": "Motif", + "placeholder": "Expliquez pourquoi vous modifiez le statut de ce contrôle…", + "confirm": "Confirmer le changement", + "cancel": "Annuler" + }, + "coverageLabel": "Couverture", + "activityLabel": "Activité", + "evidenceLabel": "Preuve", + "seeMore": "Voir plus", + "seeLess": "Voir moins", + "evaluating": "Évaluation du framework…", + "complianceScore": "Score de conformité", + "generatedAt": "Généré {{date}}", + "reportError": "Impossible de générer le rapport.", + "coverage": "{{n}} règles", + "activity": "{{n}} alertes", + "status": { + "COMPLIANT": "Conforme", + "NON_COMPLIANT": "Non conforme", + "AT_RISK": "À risque", + "NOT_COVERED": "Non couvert", + "OUT_OF_SCOPE": "Hors périmètre", + "PENDING": "En attente", + "label": "Statut", + "NOT_EVALUATED": "Not evaluated" + }, + "toast": { + "toggleError": "Échec du changement d'état du framework", + "reportGenerated": "Rapport généré", + "reportError": "Échec de la génération du rapport" + }, + "schedule": { + "new": "Nouvelle planification", + "loading": "Chargement des planifications…", + "loadError": "Impossible de charger les planifications.", + "empty": "Aucune planification pour l'instant.", + "edit": "Modifier", + "delete": "Supprimer", + "newTitle": "Nouvelle planification", + "editTitle": "Modifier la planification", + "framework": "Framework", + "cadenceLabel": "Cadence", + "cronHint": "Cron à 5 champs (min heure jour mois jourSemaine).", + "recipientsHint": "E-mails séparés par des virgules. Laissez vide pour seulement stocker le snapshot.", + "save": "Enregistrer", + "cancel": "Annuler", + "frameworkRequired": "Le framework est requis", + "cronRequired": "La planification (cron) est requise", + "cadence": { + "daily": "Quotidienne", + "weekly": "Hebdomadaire", + "monthly": "Mensuelle", + "custom": "Personnalisée" + }, + "toast": { + "saved": "Planification enregistrée", + "saveError": "Échec de l'enregistrement de la planification", + "deleted": "Planification supprimée", + "deleteError": "Échec de la suppression de la planification" + }, + "to": "To", + "cc": "Cc", + "toRequired": "At least one recipient is required", + "windowDays": "Reporting window (days)", + "windowDaysShort": "over {{days}}d", + "windowDaysHint": "How far back the report counts. Independent of how often it runs." + }, + "frameworks": { + "new": "Nouveau framework", + "edit": "Modifier", + "createTitle": "Nouveau framework", + "visualTab": "Visuel", + "codeTab": "Code", + "key": "Clé", + "name": "Nom", + "description": "Description", + "source": "Source", + "sections": "Sections", + "sectionKey": "clé de section", + "sectionName": "Nom de la section", + "requirements": "Exigences", + "reqId": "id exig.", + "reqName": "Nom de l'exigence", + "addSection": "Ajouter une section", + "addRequirement": "Ajouter une exigence", + "satisfiedBy": "satisfaite par des contrôles", + "searchControls": "Rechercher des contrôles…", + "noControls": "Aucun contrôle", + "save": "Enregistrer", + "delete": "Supprimer", + "confirmDelete": "Confirmer la suppression", + "cancel": "Annuler", + "yamlError": "Impossible d'appliquer le YAML : {{error}}", + "keyRequired": "La clé est requise", + "nameRequired": "Le nom est requis", + "toast": { + "created": "Framework créé", + "saved": "Framework enregistré", + "saveError": "Échec de l'enregistrement du framework", + "deleted": "Framework supprimé", + "deleteError": "Échec de la suppression du framework" + }, + "createControl": "Créer un nouveau contrôle…", + "createNamed": "Créer le contrôle « {{name}} »…" + }, + "controls": { + "search": "Rechercher des contrôles…", + "allFamilies": "Toutes les familles", + "new": "Nouveau contrôle", + "loading": "Chargement des contrôles…", + "loadError": "Impossible de charger les contrôles.", + "empty": "Aucun contrôle ne correspond.", + "showingOf": "Affichage de {{shown}} sur {{total}}", + "id": "ID", + "name": "Nom", + "family": "Famille", + "familyName": "Famille", + "scope": "Périmètre", + "source": "Source", + "notInLibrary": "Contrôle introuvable dans la bibliothèque", + "scopeOpt": { + "data": "Données", + "governance": "Gouvernance" + }, + "strategy": "Stratégie", + "statement": "Énoncé", + "remediation": "Remédiation", + "checks": "Vérifications", + "checksHint": "Chaque vérification exécute une requête SQL OpenSearch et applique une règle pour décider réussite/échec.", + "checkKey": "clé", + "checkName": "Nom de la vérification", + "rule": { + "MIN_HITS_REQUIRED": "Minimum de résultats requis", + "THRESHOLD_MAX": "Seuil maximum" + }, + "ruleNone": "Aucune règle", + "ruleValue": "valeur", + "addCheck": "Ajouter une vérification", + "createTitle": "Nouveau contrôle", + "visualTab": "Visuel", + "codeTab": "Code", + "save": "Enregistrer", + "delete": "Supprimer", + "confirmDelete": "Confirmer la suppression", + "cancel": "Annuler", + "yamlError": "Impossible d'appliquer le YAML : {{error}}", + "idRequired": "L'ID est requis", + "nameRequired": "Le nom est requis", + "anyDataType": "Any data type", + "addFilter": "Add filter", + "filterField": "log.eventCode", + "filterValue": "value", + "filterValues": "a, b, c", + "toast": { + "created": "Contrôle créé", + "saved": "Contrôle enregistré", + "saveError": "Échec de l'enregistrement du contrôle", + "deleted": "Contrôle supprimé", + "deleteError": "Échec de la suppression du contrôle" + } + }, + "doc": { + "title": "Rapport de conformité", + "print": "Imprimer / PDF", + "controlsEvaluated": "{{n}} contrôles évalués", + "executiveSummary": "Résumé exécutif", + "bySection": "Résultats par section", + "footer": "{{framework}} — Rapport de conformité généré {{date}} · {{brand}}", + "download": "Télécharger le PDF", + "downloadError": "Échec du téléchargement du PDF", + "error": "Impossible de générer le PDF", + "building": "Génération du document…" + }, + "locked": { + "badge": "Enterprise", + "upgrade": "Passer à Enterprise", + "upsell": "Ce framework/contrôle nécessite l'édition Enterprise." + }, + "run": "Run evaluation", + "runError": "Evaluation failed", + "noReportYet": "This framework has not been evaluated yet.", + "window": "window {{from}} → {{to}}", + "scoredOver": "{{compliant}} of {{evaluated}} requirements met · {{total}} in the framework", + "editStale": "Recorded when the engine said {{was}}; it now says {{now}}", + "checkResults": "Check results", + "verdict": "Recorded verdict", + "engineSaid": "engine said", + "hits": "hits", + "noDataFor": "no {{dataType}} data in the window", + "setStatus": "Set status", + "outcome": { + "PASSED": "Passed", + "FAILED": "Failed", + "NOT_APPLICABLE": "No data", + "ERROR": "Error" + }, + "system": "Fourni", + "addNote": "Ajouter une note", + "noteModal": { + "title": "Note", + "description": "Enregistrée dans le rapport. Ne change pas le statut du contrôle.", + "placeholder": "Remédiation en cours — ticket OPS-4412." + }, + "history": { + "title": "Score dans le temps", + "score": "Score de conformité", + "coverage": "Évalués", + "error": "Impossible de charger l’historique" + } }, - "toast": { - "labelsUpdated": "Labels mis à jour", - "labelsFailed": "Échec de la mise à jour des labels", - "deleted": "Source supprimée", - "deleteFailed": "Échec de la suppression" + "socAi": { + "title": "Configuration SOC-AI", + "subtitle": "Configurez l'agent IA qui trie les alertes et alimente l'assistant des opérations.", + "section": { + "connection": "Modèle et connexion", + "auth": "Authentification", + "behavior": "Comportement de tri des alertes", + "advanced": "Avancé" + }, + "usage": { + "title": "Utilisation", + "chat": "Complétions de chat (aujourd'hui)", + "unavailable": "L'utilisation n'est pas encore disponible.", + "resetsIn": "Réinitialisation dans {{time}}" + }, + "provider": { + "label": "Fournisseur", + "hint": "Sélectionne le format d'échange. Tout autre fournisseur qu'Anthropic utilise l'API compatible OpenAI." + }, + "model": { + "label": "Modèle", + "hint": "Identifiant du modèle exposé par le fournisseur.", + "customOption": "Modèle personnalisé…", + "customPlaceholder": "Saisissez un identifiant de modèle" + }, + "url": { + "label": "URL de l'API", + "hint": "Laissez vide pour utiliser le point de terminaison par défaut du fournisseur." + }, + "apiKey": { + "label": "Clé d'API", + "hint": "Identifiant envoyé au fournisseur.", + "setHint": "Une clé est enregistrée. Laissez vide pour la conserver." + }, + "authType": { + "label": "Type d'authentification", + "hint": "Comment les identifiants sont envoyés à votre passerelle.", + "options": { + "apiKey": "Clé API", + "bearer": "Bearer", + "customHeaders": "En-têtes personnalisés", + "none": "Aucune" + } + }, + "authHeaderName": { + "label": "Nom de l'en-tête d'authentification", + "hint": "En-tête transportant la clé (par ex. api-key pour Azure)." + }, + "authToken": { + "label": "Jeton Bearer", + "hint": "Identifiant envoyé au fournisseur.", + "setHint": "Un jeton est enregistré. Laissez vide pour le conserver." + }, + "customHeaders": { + "label": "En-têtes personnalisés", + "hint": "En-têtes supplémentaires envoyés à chaque requête. Les valeurs sont chiffrées ; « ***** » conserve celle enregistrée.", + "keyPlaceholder": "Nom de l'en-tête", + "valuePlaceholder": "Valeur", + "addRow": "Ajouter un en-tête", + "remove": "Supprimer l'en-tête" + }, + "maxTokens": { + "label": "Tokens maximum", + "hint": "Nombre maximum de tokens par réponse du LLM." + }, + "maxToolIterations": { + "label": "Itérations d'outils maximum", + "hint": "Limite de la boucle planification -> outil -> observation de l'agent." + }, + "autoAnalyze": { + "label": "Analyser automatiquement les alertes", + "hint": "Trier les alertes entrantes en temps réel." + }, + "allowIncidents": { + "label": "Autoriser la gestion des incidents", + "hint": "L'agent de tri peut créer ou mettre à jour des incidents lorsqu'il juge qu'une alerte le justifie." + }, + "changeAlertStatus": { + "label": "Modifier le statut des alertes", + "hint": "Permettre à l'agent de définir le statut d'une alerte lors du tri." + }, + "automaticIncidentCreation": { + "label": "Créer des incidents", + "hint": "Permettre à l'agent d'ouvrir des incidents à partir des alertes triées." + }, + "allowedWriteTools": { + "label": "Outils d'écriture autorisés", + "hint": "Un nom d'outil MCP par ligne que l'agent de tri peut utiliser (par ex. alerts.update_status). Les notes sont toujours autorisées." + }, + "save": "Enregistrer la configuration", + "saving": "Vérification et enregistrement...", + "saved": "Configuration SOC-AI enregistrée", + "saveError": "Échec de l'enregistrement de la configuration", + "loadError": "Échec du chargement de la configuration", + "modelRequired": "Le modèle est requis", + "applyTags": { + "label": "Appliquer des étiquettes", + "hint": "Permettre à l'agent d'étiqueter les alertes lors du tri." + }, + "note": { + "azure": "Collez l'URL complète de votre point de terminaison de déploiement Azure ; le modèle est le nom de votre déploiement. L'authentification utilise l'en-tête api-key.", + "ollama": "Pointez l'URL vers votre hôte Ollama. Aucune clé d'API n'est nécessaire pour une instance locale.", + "custom": "Tout point de terminaison compatible OpenAI. Définissez l'URL, l'authentification et les en-têtes supplémentaires requis par votre passerelle.", + "threatwinds": "Utilise automatiquement votre licence UTMStack — aucune clé API requise. Facturé via votre abonnement ThreatWinds." + }, + "chat": { + "title": "Assistant SOC", + "dashboardCreateTitle": "Créateur de tableau de bord", + "empty": "Posez n'importe quelle question sur vos alertes, vos détections ou la console — je peux enquêter et agir sur le SIEM.", + "tryPrefix": "Essayez", + "suggestion": "combien d'alertes ouvertes, regroupées par adversaire ?", + "placeholder": "Posez une question…", + "ask": "Demander", + "send": "Envoyer", + "collapse": "Réduire", + "expand": "Agrandir", + "clear": "Effacer la conversation", + "close": "Fermer", + "copy": "Copier", + "copied": "Copié", + "errorGeneric": "Une erreur s'est produite.", + "errorUnreachable": "Impossible de joindre l'assistant.", + "compacting": "Compactage du contexte…", + "dashboardEditTitle": "Éditeur de tableau de bord", + "editingDashboard": "Modification : {{name}}", + "soarEditTitle": "Éditeur de flux SOAR", + "soarCreateTitle": "Créer un flux SOAR", + "editingFlow": "Modification du flux : {{name}}" + }, + "focus": { + "alert": "Alerte", + "incident": "Incident", + "remove": "Ne plus partager avec l'assistant" + }, + "inheritance": { + "inherited": "Suit la valeur par défaut de l'instance. Enregistrer donne à ce locataire sa propre configuration.", + "own": "Ce locataire a sa propre configuration.", + "revert": "Suivre la valeur par défaut de l'instance", + "reverting": "Rétablissement…", + "reverted": "Suit désormais la valeur par défaut de l'instance" + }, + "allowance": { + "title": "Consommation d'IA aujourd'hui", + "ofLimit": "sur {{limit}} requêtes", + "denied": "requêtes — l'IA n'est pas disponible pour ce locataire", + "hint": "Défini par l'exploitant de l'instance. Réinitialisé à minuit UTC." + } }, - "sensitivity": { - "section": "Sensibilité de l'actif", - "hint": "Criticité métier (CIA, 0–3) de cet actif. Les alertes ciblant son hôte/IP sont pondérées par ces valeurs.", - "saved": "Sensibilité mise à jour", - "failed": "Échec de la mise à jour de la sensibilité", - "save": "Enregistrer", - "confidentiality": "Confidentialité", - "integrity": "Intégrité", - "availability": "Disponibilité", - "levels": { - "0": "Aucune", - "1": "Faible", - "2": "Moyenne", - "3": "Élevée" - } + "taggingRules": { + "title": "Règles d'étiquetage", + "subtitle": "Étiqueter automatiquement les alertes qui correspondent aux conditions.", + "new": "Nouvelle règle", + "refresh": "Actualiser", + "empty": "Aucune règle d'étiquetage pour l'instant.", + "loadError": "Impossible de charger les règles d'étiquetage.", + "retry": "Réessayer", + "deleteConfirm": "Supprimer la règle « {{name}} » ? Les futures alertes correspondant à ses conditions ne seront plus étiquetées.", + "toolbar": { + "search": "Rechercher par nom de règle…", + "allTags": "Toutes les étiquettes" + }, + "table": { + "rule": "Règle", + "tags": "Étiquettes", + "conditions": "Conditions", + "modifiedBy": "Modifiée par", + "modifiedDate": "Modifiée" + }, + "drawer": { + "createTitle": "Nouvelle règle d'étiquetage", + "edit": "Modifier", + "delete": "Supprimer", + "save": "Enregistrer", + "create": "Créer", + "cancel": "Annuler" + }, + "form": { + "basics": "Informations de base", + "name": "Nom de la règle", + "namePlaceholder": "par ex. Force brute SSH interne", + "description": "Description", + "descriptionPlaceholder": "Pourquoi cette règle existe et ce qu'elle étiquette.", + "tags": "Étiquettes à appliquer", + "noTags": "Aucune étiquette sélectionnée.", + "addTag": "Ajouter une étiquette", + "removeTag": "Retirer", + "noCatalog": "Aucune étiquette dans le catalogue pour l'instant.", + "createTag": "Créer une étiquette", + "newTagName": "Nom de la nouvelle étiquette", + "conditions": "Conditions (TOUTES doivent correspondre)", + "noConditions": "Au moins une condition est requise.", + "addCondition": "Ajouter une condition", + "removeCondition": "Retirer la condition", + "valuePlaceholder": "Valeur", + "valueListPlaceholder": "Valeurs séparées par des virgules", + "incomplete": "Renseignez le nom de la règle, la description, au moins une étiquette et complétez chaque condition." + }, + "view": { + "description": "Description", + "tags": "Étiquettes", + "conditions": "Conditions", + "audit": "Audit", + "createdBy": "Créée par", + "createdDate": "Créée", + "modifiedBy": "Modifiée par", + "modifiedDate": "Modifiée" + }, + "toast": { + "created": "Règle « {{name}} » créée.", + "updated": "Règle « {{name}} » mise à jour.", + "deleted": "Règle « {{name}} » supprimée.", + "createError": "Échec de la création de la règle.", + "updateError": "Échec de la mise à jour de la règle.", + "deleteError": "Échec de la suppression de la règle." + }, + "deleteTitle": "Supprimer la règle d'étiquetage" + }, + "threatIntel": { + "header": { + "matchedInEnv": "correspondances détectées dans votre environnement", + "export": "Exporter les IOCs", + "exporting": "Exportation…", + "noInstanceIocs": "Aucun indicateur d'instance — affichage de données génériques", + "noInstanceIocsHint": "Aucun indicateur observé dans vos alertes — affichage des données génériques des flux." + }, + "overview": { + "title": "Correspondances IOC", + "totalIndicators": "indicateurs au total", + "families": { + "ip": "IP", + "url": "URL", + "domain": "Domaine", + "signatures": "Signatures" + } + }, + "notConfigured": { + "title": "Threat Intelligence n'est pas configuré", + "body": "Contactez votre administrateur pour connecter une instance Cyber Mantra / ThreatWinds à cet environnement." + }, + "lookup": { + "title": "Rechercher n'importe quel indicateur", + "placeholder": "Collez une IP, domaine, hash, URL ou CVE — nous vérifierons les flux et votre environnement", + "button": "Rechercher", + "busy": "Recherche en cours…" + }, + "tabs": { + "iocs": "IOCs", + "actors": "Acteurs de menace", + "feeds": "Flux", + "analyst": "Analyste IA" + }, + "toolbar": { + "searchPlaceholders": { + "iocs": "Recherchez la valeur IOC, tag, source…", + "actors": "Recherchez acteurs, alias, techniques…", + "feeds": "Recherchez des flux…" + }, + "last24h": "Dernières 24 heures", + "filters": "Filtres", + "refresh": "Actualiser" + }, + "iocs": { + "table": { + "type": "Type", + "indicator": "Indicateur", + "reputation": "Réputation", + "tags": "Tags", + "lastSeen": "Dernière détection" + }, + "empty": "Aucune correspondance IOC.", + "loadingMore": "Chargement…", + "loadedProgress": "{{loaded}} sur {{total}} chargés. Défilez pour plus.", + "endOfResults": "Fin des résultats ({{loaded}} sur {{total}})." + }, + "drawer": { + "loading": "Chargement…", + "accuracy": "Précision :", + "actions": { + "block": "Bloquer en périphérie", + "viewEvents": "Afficher les événements correspondants", + "externalLookup": "Recherche externe", + "trackCampaign": "Suivre la campagne", + "viewIocs": "Afficher les IOCs correspondants", + "mitre": "MITRE ATT&CK" + }, + "sections": { + "timeline": "Chronologie", + "networkOrigin": "Réseau / origine", + "associationsWithCount": "Associations ({{count}})", + "geolocationsWithCount": "Géolocalisations ({{count}})", + "about": "À propos", + "activity": "Activité" + }, + "fields": { + "firstSeen": "Première détection", + "lastSeen": "Dernière détection", + "country": "Pays", + "city": "Ville", + "aso": "ASO", + "asn": "ASN", + "reputation": "Réputation", + "accuracy": "Précision", + "current": "Actuel", + "best": "Meilleur", + "worst": "Pire" + }, + "aiBrief": "Résumé IA", + "noDescription": "Aucune description disponible pour cet indicateur.", + "lastObserved": "Dernière observation {{when}}." + }, + "actors": { + "empty": "Aucun acteur trouvé." + }, + "feeds": { + "empty": "Aucun flux configuré.", + "table": { + "name": "Flux", + "type": "Type", + "accuracy": "Précision", + "header": "Flux", + "format": "Format" + }, + "download": "Télécharger le flux", + "checksum": "Somme de contrôle" + }, + "entityTypes": { + "ip": "IP", + "hostname": "Hôte", + "domain": "Domaine", + "url": "URL", + "hash": "Hash", + "cve": "CVE", + "threat": "Menace", + "entity": "Entité" + }, + "reputation": { + "alarming": "Alarmant", + "suspicious": "Suspect", + "indefinable": "Indéfini", + "fair": "Acceptable", + "trustworthy": "De confiance" + }, + "feedAccuracy": { + "level1": "Niveau 1", + "level2": "Niveau 2", + "level3": "Niveau 3" + }, + "triage": { + "title": "Triage", + "subtitle": "Paste indicators, get verdicts", + "input": "Indicators", + "placeholder": "Paste IPs, domains, URLs or hashes — one per line, or comma separated.\nDefanged values (1.2.3[.]4, hxxp://) are accepted.", + "run": "Triage", + "stop": "Stop", + "reset": "Clear", + "parsed": "{{count}} unique indicators", + "capped": "Capped at {{max}} per run.", + "progress": "{{done}} of {{total}}", + "empty": "Paste indicators above to begin.", + "indicator": "Indicator", + "type": "Type", + "verdict": "Verdict", + "reputation": "Rep", + "accuracy": "Acc", + "tags": "Tags", + "lastSeen": "Last seen", + "exportCsv": "Export CSV", + "exportStix": "Export STIX", + "stixNote": "STIX export includes malicious and suspicious rows only.", + "open": "Open", + "notConfigured": "Threat intelligence is not configured — triage needs an upstream ThreatWinds instance.", + "summary": "Summary", + "v.malicious": "Malicious", + "v.suspicious": "Suspicious", + "v.benign": "Benign", + "v.unknown": "Unknown", + "v.notFound": "Not found", + "v.invalid": "Unrecognised" + }, + "report": { + "title": "Signaler", + "subtitle": "Publier un indicateur dans le graphe ThreatWinds", + "submit": "Signaler l'indicateur", + "submitting": "Signalement…", + "error": { + "generic": "Impossible de soumettre l'indicateur. Réessayez." + }, + "value": { + "label": "Indicateur", + "placeholder": "IP, domaine, URL, hachage ou adresse e-mail" + }, + "type": { + "label": "Type", + "placeholder": "Déduit de la valeur", + "inferred": "Déduit : {{type}}", + "inferenceFailed": "Aucun type n'a pu être déduit de cette valeur. Choisissez-en un dans la liste ou saisissez-le.", + "unknown": "« {{type}} » n'est pas un type d'entité. Choisissez-en un dans la liste." + }, + "tags": { + "label": "Étiquettes", + "placeholder": "phishing, vol-de-credentials" + }, + "description": { + "label": "Notes" + }, + "reputation": { + "legend": "Réputation", + "hint": "Laissez vide si vous n'avez pas de verdict.", + "alarming": "Alarmant", + "worrying": "Préoccupant", + "concerning": "Suspect", + "indefinable": "Indéfinissable", + "adequate": "Suffisant", + "good": "Bon", + "exceptional": "Excellent" + }, + "associations": { + "legend": "Indicateurs liés", + "add": "Ajouter un indicateur lié", + "remove": "Supprimer", + "valuePlaceholder": "Valeur liée", + "typePlaceholder": "Type (facultatif)", + "modeLabel": "Relation", + "mode": { + "association": "Lié à", + "aggregation": "Fait partie de" + }, + "visibilityConflict": "N'appartient à aucun groupe de visibilité commun avec l'indicateur ci-dessus. La soumission entière serait rejetée." + }, + "attributes": { + "legend": "Détails", + "hint": "Facultatif. Les champs vides ne sont pas soumis.", + "invalidHex": "{{length}} caractères hexadécimaux attendus.", + "invalidHexAny": "Caractères hexadécimaux uniquement.", + "invalidNumber": "Un nombre est attendu." + }, + "correlate": { + "legend": "Corréler", + "hint": "Chaque attribut coché est publié comme entité distincte, liée à celle-ci.", + "count_one": "Crée {{count}} entité liée.", + "count_other": "Crée {{count}} entités liées." + }, + "scan": { + "notice": "Signaler cela met également une analyse de la cible en file d'attente." + }, + "receipt": { + "title": "Soumis", + "noVerdict": "Aucun verdict émis", + "skipped": "Non soumis, aucun type n'a pu être déduit", + "pending": "En attente que l'indicateur apparaisse dans le corpus…", + "live": "Présent dans le corpus — voir l'entité", + "processing": "Toujours en cours de traitement. Il apparaîtra quand l'ingestion sera à jour.", + "another": "Signaler un autre" + }, + "visibility": { + "legend": "Visible à" + }, + "example": "Essayer un exemple" + } }, - "console": { - "section": "Console", - "sectionHint": "Exécuter des commandes sur cet hôte via son agent (réponse en direct).", - "open": "Ouvrir la console", - "close": "Fermer", - "hint": "Saisissez une commande et appuyez sur Entrée pour l'exécuter sur l'agent.", - "running": "Exécution…", - "placeholder": "Saisissez une commande…", - "offline": "Cet agent semble hors ligne — il pourrait ne pas répondre aux commandes.", - "vars": { - "button": "Variables", - "title": "Variables de commande", - "subtitle": "Référencez-les dans les commandes sous la forme", - "add": "Nouvelle variable", - "name": "Nom", - "value": "Valeur", - "description": "Description", - "isSecret": "Secret (chiffré, masqué dans la sortie)", - "secret": "secret", - "secretHint": "Laissez vide pour conserver la valeur enregistrée.", - "save": "Enregistrer", - "cancel": "Annuler", - "edit": "Modifier", - "delete": "Supprimer", - "loading": "Chargement…", - "empty": "Aucune variable pour l'instant.", - "saved": "Variable enregistrée", - "deleted": "Variable supprimée", - "nameRequired": "Le nom est requis", - "loadError": "Échec du chargement des variables", - "saveError": "Échec de l'enregistrement de la variable", - "deleteError": "Échec de la suppression de la variable", - "insert": "Insérer", - "valueRequired": "Une valeur est requise" - }, - "disabled": "Agent hors ligne — commandes désactivées", - "connError": "Erreur de connexion", - "cmdError": "Erreur de commande", - "shellSelect": "Type de shell", - "noRemoteControl": "Cet agent a été installé avec le contrôle à distance désactivé. Il refuse les commandes, et cela ne peut être modifié que sur la machine elle-même.", - "noRemoteControlShort": "Contrôle à distance désactivé sur cet agent", - "password": { - "title": "Authentification", - "hint": "S'authentifier pour exécuter des commandes sur cet agent.", - "tfaPrompt": "Code: ", - "confirm": "OK", + "playground": { + "titleFilter": "Tester le pipeline", + "titleRule": "Tester la règle", + "noDataTypes": "Aucun type de données n'est encore attribué à ce pipeline — ajoutez-en un pour le tester.", + "dataTypeLabel": "Type de données", + "dataTypePlaceholder": "Aucun type de données disponible", + "dataTypeSingleHint": "Ce pipeline n'a qu'un seul type de données — ajoutez-en d'autres pour pouvoir choisir.", + "rawLogLabel": "Journal brut", + "rawLogPlaceholder": "Collez une ligne de journal d'exemple…", + "rawLogCounter": "{{chars}} car. · {{kb}} Ko", + "rawLogTooLarge": "Ce journal dépasse la limite de 1 Mo — réduisez-le avant d'exécuter le test.", + "run": { + "label": "Exécuter", + "running": "Test en cours…", + "waitHint": "Cela peut prendre jusqu'à 15 secondes pendant que le pipeline traite le journal." + }, + "errors": { + "busy": "Le playground exécute déjà un autre test — veuillez réessayer sous peu.", + "timeout": "Le test a expiré — cela signifie généralement que le type de données sélectionné ne correspond pas au format du journal.", + "validation": "La requête est invalide — vérifiez le journal brut et le contenu du pipeline.", + "server": "Le playground n'a pas pu terminer le test — veuillez réessayer." + }, + "notices": { + "geo": "Le plugin de géolocalisation n'est pas disponible dans cette version allégée du test de filtres et de règles.", + "correlation": "Les règles qui référencent des événements antérieurs via les clauses afterEvent ou correlation nécessitent que des événements correspondants existent déjà dans le système pour que l'alerte testée se déclenche." + }, + "result": { + "label": "Résultat analysé", + "empty": "Exécutez un test pour voir ici l'événement analysé.", + "loading": "En attente de l'événement analysé…", + "tabs": { + "fields": "Champs", + "json": "JSON" + }, + "fieldsCount_one": "{{count}} champ", + "fieldsCount_other": "{{count}} champs", + "copy": "Copier", + "copied": "Copié", + "elapsed": "Analysé en {{time}}", + "elapsedHint": "Temps entre Exécuter et le résultat analysé", + "searchPlaceholder": "Rechercher des champs…", + "noMatch": "Aucun champ ne correspond à votre recherche." + }, + "alerts": { + "label": "Alertes", + "empty": "Exécutez un test pour voir ici les alertes déclenchées.", + "none": "Aucune alerte n'a été déclenchée.", + "count_one": "{{count}} alerte", + "count_other": "{{count}} alertes" + }, + "title": "Test pipeline" + }, + "tenants": { + "title": "Locataires", + "new": "Nouveau locataire", + "subtitle": "Chaque client de cette instance, ce qu'il détient et ce qu'il vous laisse voir.", + "searchPlaceholder": "Rechercher par nom ou domaine…", + "loading": "Chargement des locataires…", + "loadFailed": "Impossible de charger les locataires.", + "retry": "Réessayer", + "none": "Aucun locataire pour le moment.", + "noSearchMatch": "Aucun locataire ne correspond à la recherche.", "cancel": "Annuler", - "authError": "Échec de l'authentification", - "authHint": "S'authentifier pour exécuter des commandes sur cet agent.", - "authOk": "Authentifié." - } - }, - "health": { - "online": "en ligne", - "offline": "hors ligne", - "total": "total" - } - }, - "adversaries": { - "title": "Vue des adversaires", - "subtitle": "Chaque IP, hôte ou utilisateur vu attaquer votre environnement, avec leurs techniques et cibles.", - "countChip": "{{count}} adversaires", - "refresh": "Actualiser", - "search": "Rechercher par IP, hôte, utilisateur, pays, ASO…", - "empty": "Aucun adversaire ne correspond.", - "loadError": "Impossible de charger les adversaires.", - "retry": "Réessayer", - "views": { - "all": "Tous", - "high": "Sévérité élevée", - "ip": "IP", - "host": "Hôtes", - "user": "Utilisateurs" - }, - "threat": { - "critical": "Critique", - "high": "Élevé", - "medium": "Moyen", - "low": "Faible" - }, - "kind": { - "ip": "IP", - "host": "Hôte", - "user": "Utilisateur" - }, - "layout": { - "list": "Liste", - "cards": "Cartes" - }, - "overview": { - "title": "Activité des adversaires · dernières 24 heures", - "high": "sévérité élevée", - "countries": "pays", - "alerts": "alertes", - "ago24": "il y a 24h", - "ago12": "il y a 12h", - "now": "maintenant" - }, - "col": { - "adversary": "Adversaire", - "threat": "Menace", - "alerts": "Alertes", - "targets": "Cibles", - "lastSeen": "Vu pour la dernière fois", - "victims": "Victimes" - }, - "card": { - "alerts": "Alertes", - "techniques": "Techniques", - "targets": "Cibles" - }, - "tabs": { - "profile": "Profil", - "techniques": "Techniques", - "targets": "Cibles", - "alerts": "Alertes" - }, - "drawer": { - "activity": "Activité sur 24 heures", - "identification": "Identification", - "kindLabel": "Type", - "identifier": "Identifiant", - "firstSeen": "Vu pour la première fois", - "lastSeen": "Vu pour la dernière fois", - "geolocation": "Géolocalisation", - "country": "Pays", - "city": "Ville", - "topTechniques": "Principales techniques", - "noTechniques": "Aucune technique enregistrée.", - "targets": "Cibles", - "noTargets": "Aucune cible enregistrée.", - "recentAlerts": "Alertes récentes", - "noAlerts": "Aucune alerte.", - "echoes": "{{count}} répétitions" - }, - "relative": { - "justNow": "à l’instant", - "minutesAgo": "il y a {{count}}m", - "hoursAgo": "il y a {{count}}h", - "daysAgo": "il y a {{count}}j" - }, - "field": { - "ip": "IP", - "host": "Hôte", - "user": "Utilisateur", - "port": "Port", - "domain": "Domaine", - "mac": "MAC", - "country": "Pays", - "city": "Ville", - "asn": "ASN", - "aso": "ASO" - } - }, - "timeRange": { - "quick": "Plages rapides", - "relative": "Relatif", - "absolute": "Absolu", - "last": "Derniers", - "apply": "Appliquer", - "allTime": "Toute la période", - "from": "De", - "to": "À", - "now": "maintenant", - "units": { - "minutes": "minutes", - "hours": "heures", - "days": "jours", - "weeks": "semaines", - "months": "mois" - }, - "presets": { - "15m": "15 dernières minutes", - "1h": "Dernière heure", - "6h": "6 dernières heures", - "24h": "24 dernières heures", - "7d": "7 derniers jours", - "30d": "30 derniers jours" - } - }, - "alerts": { - "title": "Alertes", - "matching": "{{count}} correspondances", - "subtitle": "Triez ce qui compte.", - "openNow": "ouvertes actuellement.", - "view": { - "alerts": "Alertes", - "overview": "Aperçu" - }, - "toolbar": { - "searchPlaceholder": "Rechercher par nom d'alerte…", - "allSeverities": "Toutes les sévérités", - "export": "Exporter en CSV", - "refresh": "Actualiser" - }, - "severity": { - "high": "Élevée", - "medium": "Moyenne", - "low": "Faible" - }, - "status": { - "open": "Ouverte", - "in_review": "En cours de revue", - "completed": "Terminée", - "auto": "Revue automatique" - }, - "statusTabs": { - "all": "Toutes" - }, - "overview": { - "overTime": "Alertes dans le temps", - "matchingAlerts": "alertes correspondantes", - "noData": "Aucune donnée.", - "bySeverity": "Par sévérité", - "byStatus": "Par statut" - }, - "filters": { - "add": "Ajouter un filtre", - "clearAll": "Tout effacer", - "filterValues": "Filtrer les valeurs…", - "loadingValues": "Chargement des valeurs…", - "noValues": "Aucune valeur trouvée.", - "pickValue": "Choisissez une valeur pour ajouter le filtre.", - "empty": "(vide)", - "cancel": "Annuler", - "addBtn": "Ajouter" - }, - "ops": { - "CONTAIN": "contient", - "IS": "est", - "IS_NOT": "n'est pas", - "EXIST": "existe", - "DOES_NOT_EXIST": "n'existe pas" - }, - "fields": { - "adversary_domain": "Domaine de l'adversaire", - "adversary_geolocation_asn": "ASN de l'adversaire", - "adversary_geolocation_aso": "ASO de l'adversaire", - "adversary_geolocation_country": "Pays de l'adversaire", - "adversary_host": "Hôte de l'adversaire", - "adversary_ip": "IP de l'adversaire", - "adversary_url": "URL de l'adversaire", - "adversary_user": "Utilisateur de l'adversaire", - "assignee": "Assigné à", - "category": "Catégorie", - "dataSource": "Capteur", - "dataType": "Type de données", - "description": "Description", - "id": "ID", - "impactScore": "Risque", - "impact_availability": "Disponibilité", - "impact_confidentiality": "Confidentialité", - "impact_integrity": "Intégrité", - "incidentDetail_incidentName": "Nom de l'incident", - "incidentDetail_incidentId": "Id de l'incident", - "isIncident": "Est un incident", - "name": "Nom de l'alerte", - "notes": "Notes", - "severity": "Sévérité", - "status": "Statut", - "tags": "Étiquettes", - "target_domain": "Domaine de la cible", - "target_geolocation_asn": "ASN de la cible", - "target_geolocation_aso": "ASO de la cible", - "target_geolocation_country": "Pays de la cible", - "target_host": "Hôte de la cible", - "target_ip": "IP de la cible", - "target_url": "URL de la cible", - "target_user": "Utilisateur de la cible", - "technique": "Technique" - }, - "tagFilter": { - "tags": "Étiquettes", - "tag_one": "{{count}} étiquette", - "tag_other": "{{count}} étiquettes", - "clearSelection": "Effacer la sélection", - "noTags": "Pas d'étiquettes" - }, - "bulk": { - "selected": "{{count}} sélectionnées", - "setStatus": "Définir le statut", - "addTag": "Ajouter une étiquette", - "noTags": "Pas d'étiquettes", - "addToIncident": "Ajouter à un incident", - "clear": "Effacer" - }, - "tagEditor": { - "tag": "Étiquette", - "noTagsYet": "Pas encore d'étiquettes", - "createTag": "Créer une étiquette", - "newTagName": "Nom de la nouvelle étiquette…", - "createApply": "Créer et appliquer l’étiquette", - "save": "Enregistrer", - "cancel": "Annuler", - "edit": "Modifier l'étiquette", - "delete": "Supprimer l'étiquette", - "systemLocked": "Étiquette système (verrouillée)", - "alreadyExists": "Cette étiquette existe déjà.", - "color": "Couleur {{color}}", - "createRule": "Créer une règle d'étiquetage avec cette étiquette" - }, - "table": { - "actions": "Actions", - "alert": "Alerte", - "status": "Statut", - "technique": "Technique", - "severity": "Gravité", - "risk": "Risque", - "echoes": "Échos", - "time": "Heure", - "riskHint": "Score de risque (0–100), coloré selon la gravité", - "source": "Source", - "adversary": "Adversaire" - }, - "row": { - "createRuleFromAlert": "Créer une étiquette à partir de cette alerte", - "createIncident": "Créer un incident à partir de cette alerte", - "viewIncident": "Voir les détails de l'incident", - "assignedTo": "Attribuée à {{user}}", - "echoesTooltip": "{{count}} échos — cliquez pour développer", - "echoesEmpty": "Aucun écho enregistré" - }, - "echoes": { - "title": "{{count}} échos", - "close": "Fermer", - "empty": "Aucun écho enregistré pour cette alerte.", - "loadError": "Impossible de charger les échos." - }, - "list": { - "loading": "Chargement des alertes…", - "loadError": "Impossible de charger les alertes.", - "retry": "Réessayer", - "empty": "Aucune alerte ne correspond à cette vue." - }, - "badge": { - "incident": "Incident", - "aiAssessed": "Évalué par IA" - }, - "drawer": { - "setStatus": "Définir le statut", - "completeFalsePositive": "Terminer + faux positif", - "addToIncident": "Ajouter à un incident", - "partOfIncident": "Partie d'un incident", - "tabs": { - "summary": "Résumé", - "parties": "Parties", - "events": "Événements", - "history": "Historique" - }, - "section": { - "description": "Description", - "solution": "Solution", - "references": "Références", - "details": "Détails", - "yourNotes": "Vos notes", - "notes": "Notes" - }, - "details": { - "severity": "Gravité", - "risk": "Risque", - "category": "Catégorie", - "technique": "Technique", - "sensor": "Capteur", - "dataType": "Type de donnée", - "alertId": "ID d'alerte", - "statusNote": "Note de statut", - "assignee": "Personne assignée" - }, - "incidentDetail": { - "incident": "Incident", - "id": "ID", - "createdBy": "Créé par", - "created": "Créé" - }, - "notesPlaceholder": "Ajouter des notes d'investigation…", - "saveNotes": "Enregistrer les notes", - "assignee": "Attribuer", - "assign": "Attribuer", - "unassign": "Désattribuer", - "unassigned": "Non attribuée", - "loadingUsers": "Chargement des utilisateurs…", - "observationLabel": "Observation", - "observationPlaceholder": "Ajouter une observation…", - "cancel": "Annuler", - "continue": "Continuer" - }, - "related": { - "sample": "Un échantillon de jusqu’à ~11 événements que le moteur a stockés sur cette alerte. Utilisez « Voir tous les journaux associés » pour l’ensemble complet et non plafonné.", - "loadingEchoes": "Chargement des événements de ses échos…", - "sampleWithEchoes": "Les événements stockés sur cette alerte et sur ses {{count}} échos ({{read}} lus). Utilisez « Voir tous les journaux associés » pour l’ensemble complet et non plafonné.", - "empty": "Aucun événement d’échantillon stocké sur cette alerte. Chargez l’ensemble corrélé complet dans l’Explorateur de journaux.", - "viewAll": "Voir tous les journaux associés" - }, - "party": { - "source": "Source / cible", - "adversary": "Adversaire", - "noData": "Aucune donnée.", - "ip": "IP", - "host": "Hôte", - "user": "Utilisateur", - "domain": "Domaine", - "country": "Pays" - }, - "history": { - "empty": "Aucun historique enregistré.", - "by": "par {{user}}", - "actions": { - "UPDATE_STATUS": "Statut mis à jour", - "UPDATE_TAGS": "Étiquettes mises à jour", - "UPDATE_NOTES": "Notes mises à jour", - "UPDATE_SOLUTION": "Solution mise à jour", - "MARK_AS_INCIDENT": "Marquée comme incident" - }, - "detail": { - "statusTo": "Statut → {{status}}", - "tags": "Étiquettes : {{tags}}", - "aiAdded": "Évaluation IA ajoutée", - "observationAdded": "Observation ajoutée", - "notesUpdated": "Notes mises à jour" - } - }, - "ai": { - "title": "Évaluation IA du SOC", - "risk": "risque {{risk}}", - "score": "{{score}}/100", - "generate": "Générer le résumé IA", - "hint": "SOC-AI analyse cette alerte et ajoute une évaluation.", - "generating": "Analyse de l'alerte en cours… cela peut prendre une minute.", - "ready": "Résumé IA prêt", - "failed": "Impossible de générer le résumé IA", - "slow": "Le résumé IA prend plus de temps que prévu. Il apparaîtra sur l'alerte dès qu'il sera prêt." - }, - "incident": { - "titleAdd_one": "Ajouter {{count}} alerte à un incident", - "titleAdd_other": "Ajouter {{count}} alertes à un incident", - "new": "Nouvel incident", - "existing": "Incident existant", - "nameLabel": "Nom de l'incident", - "namePlaceholder": "p. ex. Intrusion présumée de Scattered Spider", - "descriptionLabel": "Description", - "descriptionPlaceholder": "Résumé facultatif…", - "pickLabel": "Choisir un incident", - "loading": "Chargement…", - "selectPlaceholder": "Sélectionner un incident…", - "willLink_one": "{{count}} alerte sera liée.", - "willLink_other": "{{count}} alertes seront liées.", - "cancel": "Annuler", - "create": "Créer l'incident", - "add": "Ajouter à un incident" - }, - "toast": { - "statusUpdated": "Statut mis à jour", - "statusFailed": "Échec de la mise à jour du statut", - "tagsUpdated": "Étiquettes mises à jour", - "tagsFailed": "Échec de la mise à jour des étiquettes", - "tagCreateFailed": "Échec de la création de l'étiquette", - "tagUpdated": "Étiquette mise à jour", - "tagUpdateFailed": "Échec de la mise à jour de l'étiquette", - "tagDeleted": "Étiquette supprimée", - "tagDeleteFailed": "Échec de la suppression de l'étiquette", - "notesSaved": "Notes enregistrées", - "notesFailed": "Échec de l'enregistrement des notes", - "exportFailed": "Échec de l'export CSV", - "noRelatedLogs": "Aucun journal associé trouvé pour cette alerte", - "relatedLogsFailed": "Échec du chargement des journaux associés", - "incidentCreated": "Incident créé", - "alertsAdded": "Alertes ajoutées à l'incident", - "incidentFailed": "Échec de l'enregistrement de l'incident", - "assigned": "Alerte attribuée", - "unassigned": "Alerte désattribuée", - "assignFailed": "Impossible de mettre à jour l'attribution", - "newAlertsToast_title": "Nouvelles alertes", - "newAlertsToast_count_one": "{{count}} nouvelle alerte", - "newAlertsToast_count_other": "{{count}} nouvelles alertes", - "newAlertsToast_view": "Voir" - } - }, - "incidents": { - "title": "Incidents", - "subtitle": "Regroupez, triez et résolvez les alertes liées en incidents.", - "refresh": "Actualiser", - "count_one": "{{count}} incident", - "count_other": "{{count}} incidents", - "openNow": "ouverts actuellement", - "empty": "Aucun incident correspondant.", - "loadError": "Impossible de charger les incidents.", - "retry": "Réessayer", - "unassigned": "Non attribué", - "unknownUser": "Inconnu", - "status": { - "open": "Ouvert", - "in_review": "En revue", - "completed": "Terminé", - "merged": "Fusionné" - }, - "sev": { - "high": "Élevée", - "medium": "Moyenne", - "low": "Faible", - "unknown": "Non évaluée" - }, - "toolbar": { - "search": "Rechercher des incidents…", - "create": "Créer un incident", - "allSeverities": "Toutes les sévérités", - "export": "Exporter en CSV" - }, - "statusTabs": { - "all": "Tous" - }, - "filters": { - "add": "Ajouter un filtre", - "clearAll": "Tout effacer", - "filterValues": "Filtrer les valeurs…", - "loadingValues": "Chargement des valeurs…", - "noValues": "Aucune valeur trouvée.", - "pickValue": "Choisissez une valeur pour ajouter le filtre.", - "empty": "(vide)", - "cancel": "Annuler", - "addBtn": "Ajouter" - }, - "ops": { - "IS": "est" - }, - "layout": { - "table": "Tableau", - "board": "Kanban" - }, - "table": { - "name": "Incident", - "status": "Statut", - "severity": "Sévérité", - "assignee": "Assigné", - "alerts": "Alertes", - "created": "Créé" - }, - "drawer": { - "created": "Créé {{date}}", - "alertsCount": "{{count}} alertes", - "solutionPlaceholder": "Résolution / notes de remédiation…", - "solutionHint": "Enregistré lors du passage de l’incident à Terminé.", - "tabs": { - "overview": "Aperçu", - "alerts": "Alertes", - "notes": "Notes", - "history": "Historique" - }, - "section": { - "description": "Description", - "solution": "Solution", - "details": "Détails" - }, - "details": { - "id": "ID", - "status": "Statut", - "severity": "Sévérité", - "assignee": "Assigné", - "created": "Créé", - "alerts": "Alertes liées" - } - }, - "alerts": { - "empty": "Aucune alerte liée à cet incident.", - "remove": "Dissocier l’alerte", - "removeConfirm": "Dissocier « {{name}} » de cet incident ?", - "removed": "Alerte dissociée", - "removeError": "Impossible de dissocier l’alerte", - "loadingAlert": "Chargement de l'alerte…", - "alertGone": "Cette alerte n'est plus dans le stockage — la rétention l'a peut-être supprimée.", - "alertFailed": "Impossible de charger l'alerte.", - "openInAlerts": "Ouvrir dans Alertes" - }, - "notes": { - "empty": "Pas encore de notes.", - "add": "Ajouter une note", - "addError": "Impossible d’ajouter la note", - "placeholder": "Écrire une note…" - }, - "history": { - "empty": "Pas encore d’historique." - }, - "toast": { - "statusChanged": "Statut de l’incident mis à jour", - "statusError": "Impossible de changer le statut", - "exportFailed": "Échec de l'export CSV" - }, - "assign": { - "assign": "Assigner", - "search": "Rechercher des utilisateurs…", - "unassign": "Désassigner", - "noUsers": "Aucun utilisateur", - "assigned": "Assigné à {{user}}", - "unassigned": "Incident désassigné", - "error": "Impossible de changer l’assigné", - "custom": "Assigner personnalisé", - "customPlaceholder": "Saisir un identifiant…" - }, - "action": { - "INCIDENT_CREATED": "Incident créé", - "INCIDENT_ALERT_ADD": "Alertes ajoutées", - "INCIDENT_ALERT_STATUS_CHANGED": "Statut des alertes modifié", - "INCIDENT_STATUS_CHANGE": "Statut modifié", - "INCIDENT_NOTE_ADD": "Note ajoutée", - "INCIDENT_NOTE_CHANGE": "Note modifiée", - "INCIDENT_ASSIGNED": "Attribution modifiée" - }, - "create": { - "title": "Créer un incident", - "stepIndicator": "Étape {{current}} sur {{total}}", - "selectedCount": "{{count}} alertes sélectionnées", - "submit": "Créer", - "success": "Incident créé", - "error": "Impossible de créer l'incident", - "details": { - "nameLabel": "Nom", - "namePlaceholder": "Titre court et descriptif", - "descriptionLabel": "Description", - "descriptionPlaceholder": "Contexte, portée, notes initiales…" - } - } - }, - "alertingRules": { - "title": "Règles d’alerte", - "subtitle": "Règles de corrélation qui transforment les événements en alertes. Activez, ajustez ou créez les vôtres.", - "new": "Nouvelle règle", - "refresh": "Actualiser", - "empty": "Aucune règle correspondante.", - "loadError": "Impossible de charger les règles.", - "retry": "Réessayer", - "deleteConfirm": "Supprimer la règle « {{name}} » ?", - "adversary": { - "origin": "Origine", - "target": "Cible" - }, - "state": { - "active": "Active", - "inactive": "Inactive" - }, - "owner": { - "system": "Système", - "custom": "Personnalisée" - }, - "toolbar": { - "search": "Rechercher des règles…", - "allCategories": "Toutes les catégories", - "allAdversaries": "Tous les adversaires", - "allStates": "Tous les états", - "allOwners": "Toutes les origines", - "allDataTypes": "Tous les types" - }, - "table": { - "name": "Règle", - "category": "Catégorie", - "technique": "Technique", - "adversary": "Adversaire", - "impact": "Impact", - "active": "Active", - "dataTypes": "Types de données", - "selectAll": "Tout sélectionner", - "selectRow": "Sélectionner {{name}}" - }, - "export": { - "all": "Tout exporter", - "selected": "Exporter ({{count}})", - "error": "Impossible d’exporter les règles" - }, - "view": { - "description": "Description", - "details": "Détails", - "impact": "Impact (C·I·D)", - "dataTypes": "Types de données", - "updated": "Mise à jour", - "relPath": "Chemin", - "definition": "Condition (CEL)", - "correlationSteps": "Étapes de corrélation", - "correlation": "Corrélation", - "groupBy": "Grouper par", - "deduplicateBy": "Dédupliquer par", - "references": "Références" - }, - "editor": { - "createTitle": "Nouvelle règle", - "edit": "Modifier", - "delete": "Supprimer", - "export": "Exporter", - "cancel": "Annuler", - "save": "Enregistrer", - "metadata": "Métadonnées", - "name": "Nom", - "confidentiality": "Confidentialité", - "integrity": "Intégrité", - "availability": "Disponibilité", - "dataTypes": "Types de données", - "dataTypesHint": "séparés par des virgules", - "activeOnSave": "Active", - "definitionSection": "Définition", - "where": "Condition (CEL)", - "whereHint": "Expression CEL évaluée par événement", - "correlationSteps": "Étapes de corrélation", - "correlationStepsHint": "tableau JSON", - "jsonArray": "tableau JSON", - "nameRequired": "Le nom est requis", - "definitionRequired": "La condition est requise", - "invalidJson": "Un champ de la définition contient du JSON invalide", - "addStep": "Ajouter une étape de corrélation", - "step": "Étape {{n}}", - "removeStep": "Supprimer l’étape", - "indexPattern": "Modèle d’index", - "within": "Fenêtre", - "count": "Nombre", - "conditions": "Conditions", - "field": "Champ", - "value": "Valeur", - "addCondition": "Ajouter une condition", - "orGroup": "Groupe Or {{n}}", - "addOr": "Ajouter un groupe Or", - "removeOr": "Supprimer", - "fieldsHint": "noms de champs", - "referencesHint": "URLs", - "visual": "Visuel", - "code": "Code", - "dataTypesPick": "Sélectionner…", - "dataTypesSearch": "Rechercher des types…", - "dataTypesNone": "Aucun type de données", - "visualTab": "Visuel", - "codeTab": "Code", - "yamlError": "Impossible d'appliquer le YAML : {{error}}", - "test": "Test" - }, - "toast": { - "activated": "Règle activée", - "deactivated": "Règle désactivée", - "toggleError": "Impossible de changer l’état de la règle", - "deleted": "Règle supprimée", - "deleteError": "Impossible de supprimer la règle", - "created": "Règle créée", - "saved": "Règle enregistrée", - "saveError": "Impossible d’enregistrer la règle" - }, - "operator": { - "filter_term": "égal (term)", - "must_not_term": "différent (term)", - "filter_match": "correspond (texte)", - "must_not_match": "ne correspond pas (texte)" - }, - "where": { - "matchPrefix": "Correspond à", - "all": "toutes", - "any": "au moins une", - "matchSuffix": "de ces conditions :", - "negate": "Nier", - "listHint": "séparés par des virgules", - "advanced": "Cette condition utilise du CEL avancé — modifiez-la en Code ou reconstruisez-la visuellement.", - "and": "ET", - "or": "OU" - }, - "celOp": { - "exists": "existe", - "equals": "égal à", - "equalsIgnoreCase": "égal (sans casse)", - "contains": "contient", - "oneOf": "est l’un de", - "containsAll": "contient tous", - "startsWith": "commence par", - "endsWith": "finit par", - "regexMatch": "regex", - "lessThan": "<", - "lessOrEqual": "≤", - "greaterThan": ">", - "greaterOrEqual": "≥", - "inCIDR": "dans CIDR", - "isHour": "l’heure est", - "isMinute": "la minute est", - "isDayOfWeek": "le jour est", - "isWeekend": "est le week-end", - "isWorkDay": "est un jour ouvré", - "isBetweenTime": "heure entre" - }, - "import": { - "button": "Importer", - "error": "Échec de l'importation", - "resultTitle": "Résultats de l'import", - "approved": "Approuvés", - "rejected": "Rejetés", - "done": "Terminé" - }, - "test": "Test" - }, - "regexPatterns": { - "title": "Expressions régulières", - "subtitle": "Expressions régulières réutilisables référencées par les filtres d'analyse.", - "new": "Nouveau motif", - "search": "Rechercher des motifs…", - "refresh": "Actualiser", - "view": "Voir", - "system": "Système", - "user": "Personnalisé", - "loading": "Chargement des motifs…", - "loadError": "Impossible de charger les motifs.", - "retry": "Réessayer", - "empty": "Aucun motif ne correspond à cette vue.", - "tabs": { - "all": "Tous", - "system": "Système", - "user": "Personnalisés" - }, - "cols": { - "pattern": "Motif", - "definition": "Définition", - "type": "Type" - }, - "editor": { - "titleNew": "Nouveau motif", - "patternId": "ID du motif", - "patternIdHint": "Nom unique référencé depuis les filtres.", - "description": "Description", - "descriptionPlaceholder": "Ce que ce motif reconnaît (facultatif)", - "definition": "Définition (regex)", - "definitionHint": "Une expression régulière. Peut référencer d'autres motifs.", - "readOnly": "Motif système — en lecture seule.", - "save": "Enregistrer", - "saving": "Enregistrement…", - "delete": "Supprimer", - "confirmDelete": "Confirmer la suppression", - "cancel": "Annuler" - }, - "toast": { - "saved": "Motif enregistré", - "saveError": "Échec de l'enregistrement du motif", - "deleted": "Motif supprimé", - "deleteError": "Échec de la suppression du motif", - "patternIdRequired": "L'ID du motif est requis", - "definitionRequired": "La définition est requise" - } - }, - "parsingFilters": { - "title": "Pipelines", - "subtitle": "Pipelines YAML appliqués aux logs lors de leur analyse à l'ingestion.", - "new": "Nouveau pipeline", - "search": "Rechercher des pipelines…", - "refresh": "Actualiser", - "view": "Voir", - "system": "Système", - "user": "Personnalisé", - "loading": "Chargement des pipelines…", - "loadError": "Impossible de charger les pipelines.", - "retry": "Réessayer", - "empty": "Aucun pipeline ne correspond à cette vue.", - "tabs": { - "all": "Tous", - "active": "Actifs", - "inactive": "Inactifs", - "system": "Système", - "user": "Personnalisés" - }, - "cols": { - "filter": "Pipeline", - "type": "Type", - "active": "Actif", - "dataTypes": "Types de données", - "order": "Ordre", - "moveUp": "Monter", - "moveDown": "Descendre", - "actions": "Actions" - }, - "editor": { - "titleNew": "Nouveau pipeline", - "titleEdit": "Modifier le pipeline", - "titleSystem": "Pipeline (système)", - "name": "Nom", - "namePlaceholder": "Mon pipeline personnalisé", - "nameHint": "Sera enregistré sous {{file}}", - "namePending": "Choisissez un nom — il deviendra le nom du fichier.", - "content": "Contenu (YAML pipeline)", - "contentHint": "Une définition YAML pipeline: valide.", - "readOnly": "Pipeline système — en lecture seule. Vous pouvez seulement l'activer ou le désactiver.", - "save": "Enregistrer", - "saving": "Enregistrement…", - "delete": "Supprimer", - "confirmDelete": "Confirmer la suppression", - "cancel": "Annuler", - "test": "Test" - }, - "toast": { - "saved": "Pipeline enregistré", - "saveError": "Échec de l'enregistrement du pipeline", - "deleted": "Pipeline supprimé", - "deleteError": "Échec de la suppression du pipeline", - "activateError": "Échec du changement d'état du pipeline", - "nameRequired": "Le nom est requis", - "contentRequired": "Le contenu est requis", - "orderError": "Échec du changement d'ordre du pipeline" - }, - "visual": { - "visualTab": "Visuel", - "codeTab": "Code", - "codeOnly": "Passez au Code — ce contenu ne peut pas être affiché visuellement.", - "cantParse": "Impossible d'ouvrir l'éditeur visuel : {{error}}", - "dataTypes": "Types de données", - "steps": "Étapes", - "noSteps": "Aucune étape.", - "addStep": "Ajouter une étape :", - "removeStep": "Supprimer l'étape", - "moveUp": "Monter", - "moveDown": "Descendre", - "whereHint": "condition optionnelle (CEL)", - "addValue": "Ajouter une valeur", - "addPattern": "Ajouter un motif", - "rawHint": "Ce processeur s'édite en YAML brut.", - "rawNotMap": "Doit être un ensemble de champs clé : valeur.", - "dataTypesPick": "Choisir des types de données", - "dataTypesSearch": "Rechercher des types de données…", - "dataTypesNone": "Aucun type de données", - "dataTypesAdd": "Ajouter « {{value}} »", - "insertPattern": "Insérer un motif regex", - "patternSearch": "Rechercher des motifs…", - "patternNone": "Aucun motif", - "newPattern": "Nouveau motif…", - "createInsert": "Créer et insérer", - "patternCreated": "Motif « {{name}} » créé", - "patternCreateError": "Échec de la création du motif", - "patternIdInvalid": "L'ID du motif doit commencer par une lettre ou _ et n'utiliser que des lettres, chiffres ou _", - "patternDefRequired": "La définition est requise", - "parameters": "Paramètres", - "paramsKey": "Clé", - "paramsValue": "Valeur", - "entry": "Entrée {{n}}", - "order": "ordre {{n}}", - "orderLabel": "Ordre", - "removeEntry": "Supprimer l’entrée", - "addEntry": "Ajouter une entrée de pipeline", - "collapse": "Replier", - "expand": "Déplier", - "splitHint": "Vacío equivale a un espacio por defecto — en el YAML siempre aparece como fieldSplit: \" \"." - }, - "allDataTypes": "Tous les types de données", - "testPipeline": "Test pipeline" - }, - "soar": { - "title": "SOAR", - "subtitle": "Flux de réponse automatique : les conditions correspondent à une alerte, les commandes s'exécutent sur l'agent.", - "comingSoon": "Bientôt disponible", - "console": { - "loading": "Chargement des agents…", - "loadError": "Impossible de charger les agents.", - "pickAgent": "Sélectionner un agent", - "pickAgentHint": "Choisissez un agent dans la liste pour ouvrir sa console interactive.", - "lockedAgent": "Contrôle à distance désactivé" - }, - "search": "Rechercher des flux…", - "refresh": "Actualiser", - "new": "Nouveau flux", - "view": "Voir", - "system": "Système", - "loading": "Chargement des flux…", - "loadError": "Impossible de charger les flux.", - "retry": "Réessayer", - "empty": "Aucun flux ne correspond à cette vue.", - "templates": { - "title": "Nouveau flux", - "subtitle": "Choisis un modèle d'action ou pars de zéro.", - "loading": "Chargement des modèles…", - "loadError": "Impossible de charger les modèles.", - "empty": "Aucun modèle disponible.", - "cancel": "Annuler", - "scratch": "Partir de zéro" - }, - "tabs": { - "flows": "Flux", - "executions": "Historique d'exécutions", - "all": "Tous", - "active": "Actifs", - "inactive": "Inactifs", - "system": "Système", - "user": "Personnalisés" - }, - "cols": { - "flow": "Flux", - "platform": "Plateforme", - "conditions": "Conditions", - "commands": "Commandes", - "active": "Actif", - "lastRun": "Dernière exécution", - "failedRuns_one": "{{count}} exécution échouée", - "failedRuns_other": "{{count}} exécutions échouées" - }, - "operator": { - "IS": "est", - "IS_NOT": "n'est pas", - "CONTAINS": "contient", - "NOT_CONTAINS": "ne contient pas", - "EXISTS": "existe", - "NOT_EXISTS": "n'existe pas", - "START_WITH": "commence par", - "NOT_START_WITH": "ne commence pas par", - "ENDS_WITH": "se termine par", - "NOT_ENDS_WITH": "ne se termine pas par", - "IS_ONE_OF": "est l'un de", - "IS_NOT_ONE_OF": "n'est pas l'un de" - }, - "toast": { - "created": "Flux créé", - "saved": "Flux enregistré", - "saveError": "Échec de l'enregistrement du flux", - "deleted": "Flux supprimé", - "deleteError": "Échec de la suppression du flux", - "activateError": "Échec du changement d'état du flux" - }, - "editor": { - "createTitle": "Nouveau flux", - "visualTab": "Visuel", - "codeTab": "Code", - "name": "Nom", - "description": "Description", - "conditions": "Conditions", - "conditionsHint": "Le flux s'exécute quand une alerte remplit TOUTES ces conditions.", - "field": "champ", - "value": "valeur", - "valueList": "valeurs séparées par des virgules", - "addCondition": "Ajouter une condition", - "commands": "Commandes", - "commandsHint": "Exécutées dans l'ordre sur l'agent. Utilisez $(field.path) pour les valeurs de l'alerte et $[variables.NAME] pour les variables enregistrées.", - "addCommand": "Ajouter une commande", - "templatesButton": "Commandes courantes", - "templates": { - "isolate": "Isoler du réseau", - "shutdown": "Éteindre la machine", - "killProcess": "Tuer le processus", - "logout": "Déconnecter l'utilisateur", - "disableUser": "Désactiver l'utilisateur", - "blockIp": "Bloquer l'IP", - "restart": "Redémarrer la machine", - "uninstall": "Désinstaller l'application" - }, - "connector": { - "always": "toujours", - "success": "en cas de succès", - "failure": "en cas d'échec" - }, - "agentPlatform": "Plateforme de l'agent", - "shell": "Shell", - "shellAuto": "auto", - "whereToRun": "Où exécuter", - "run": { - "all": "Tous les agents", - "specific": "Un agent", - "except": "Tous sauf", - "allHint": "S'exécute sur tous les agents correspondant à cette plateforme." - }, - "selectAgentPlaceholder": "Sélectionner un agent…", - "excludedAgentsHint": "saisissez un nom d'hôte et appuyez sur Entrée", - "save": "Enregistrer", - "delete": "Supprimer", - "confirmDelete": "Confirmer la suppression", - "cancel": "Annuler", - "yamlError": "Impossible d'appliquer le YAML : {{error}}", - "nameRequired": "Le nom est requis", - "conditionsRequired": "Au moins une condition avec un champ est requise", - "commandsRequired": "Au moins une commande est requise", - "httpUrlInvalid": "Le nœud HTTP \"{{id}}\" a une URL invalide — elle doit être une URL http(s) valide.", - "httpBodyInvalid": "Le corps du nœud HTTP \"{{id}}\" n'est pas un JSON valide : {{error}}", - "incidentNameRequired": "Le nœud d'incident \"{{id}}\" nécessite un nom.", - "mailToRequired": "Le nœud d'e-mail \"{{id}}\" nécessite au moins un destinataire.", - "mailAddressInvalid": "Le nœud d'e-mail \"{{id}}\" contient une adresse {{field}} non valide : {{address}}.", - "mailSubjectRequired": "Le nœud d'e-mail \"{{id}}\" nécessite un objet.", - "identityModalTitle": "Détails du flux", - "platformRequired": "La plateforme de l'agent est requise", - "nameLabel": "Nom", - "namePlaceholder": "Nom du flux", - "descriptionLabel": "Description", - "descriptionHint": "Que fait ce flux ? (optionnel)", - "when": "Quand", - "whenTitle": "Une alerte remplit toutes ces conditions", - "on": "Sur", - "onTitle": "L'agent correspondant", - "thenRun": "Alors exécuter", - "thenTitle": "Ces commandes, dans l'ordre", - "selectField": "Choisir un champ…", - "selectPlatform": "Choisir une plateforme…", - "searchAgents": "Rechercher des agents…", - "noAgents": "Aucun agent", - "insertInto": "Insérer dans la commande {{n}} :", - "insertField": "Champ d'alerte", - "variables": "Variables", - "canvas": { - "node": "Nœud", - "deleteNode": "Supprimer le nœud", - "id": "ID", - "kind": "Type", - "executor": "Exécuteur", - "commandLabel": "Commande", - "paramsJson": "Paramètres (JSON)", - "dragToResize": "Glisser pour redimensionner", - "templatesLabel": "Modèles", - "templatesNeedPlatform": "Sélectionnez d'abord la plateforme cible", - "handlesHint": "Glissez depuis la poignée verte (en bas à gauche) pour on_success et depuis la rouge (en bas à droite) pour on_error. Plusieurs liens = parallèle. Plusieurs liens vers un même nœud = AND-join.", - "invalidJson": "JSON invalide", - "hidePalette": "Masquer la palette", - "hideInspector": "Masquer l'inspecteur", - "paletteLabel": "Palette", - "nodeShort": "Nœud", - "showPanel": "Afficher {{name}}", - "platform": "Plateforme", - "shell": "Shell", - "any": "toutes", - "auto": "auto", - "runOn": "Exécuter sur", - "runAutoTitle": "S'exécute sur l'hôte à l'origine de l'alerte", - "runSpecificTitle": "Épingler à un hôte (ou un modèle comme $(alert.foo))", - "runExceptTitle": "S'exécute sur l'hôte à l'origine de l'alerte, en excluant ceux de la liste", - "runAutoLabel": "source d'alerte", - "runSpecificLabel": "un hôte", - "runExceptLabel": "tous sauf", - "runAutoHint": "S'exécute sur $(alert.dataSource) — l'hôte à l'origine de l'alerte.", - "pickHost": "choisir un hôte…", - "orTemplateHint": "Ou saisissez un modèle — $(alert.field) est résolu à chaque exécution.", - "addExclusion": "ajouter une exclusion", - "searchAgents": "rechercher des agents…", - "noAgents": "aucun agent", - "insertField": "Insérer un champ", - "alert": "Alerte", - "wholeOutput": "sortie complète (éditez le chemin)", - "noAncestorsHint": "Aucun ancêtre d'enrichissement — ajoutez un nœud d'enrichissement en amont pour exposer sa sortie ici.", - "inserts": "insère", - "conditionalHint": "Toutes les conditions doivent correspondre. Correspondance → branche succès (verte) ; échec → branche erreur (rouge).", - "http": { - "url": "URL", - "urlInvalid": "URL http(s) invalide.", - "method": "Méthode", - "body": "Corps (JSON)", - "bodyInvalid": "JSON invalide", - "headers": "En-têtes HTTP", - "params": "Paramètres de requête", - "key": "Clé", - "value": "Valeur", - "addHeader": "Ajouter un en-tête", - "addParam": "Ajouter un paramètre" + "saving": "Enregistrement…", + "chips": { + "total": "locataires", + "active": "actifs", + "readable": "accessibles" }, - "incident": { - "name": "Nom de l'incident", - "namePlaceholder": "Ex. Connexion suspecte sur $(alert.dataSource)", - "description": "Description", - "descriptionPlaceholder": "Contexte facultatif pour les intervenants. Les gabarits comme $(alert.name) sont interpolés." - }, - "llm": { - "prompt": "Prompt", - "hint": "Le modèle est instruit de toujours répondre avec un seul objet JSON portant la propriété \"result\" ; le backend garantit ce format même si le modèle s'écarte. Les nœuds enfants s'y réfèrent via $({{nodeId}}.result) ou des champs spécifiques." - }, - "mail": { - "to": "À (séparés par une virgule)", - "cc": "CC (séparés par une virgule, facultatif)", - "addressInvalid": "Adresse e-mail non valide : {{address}}", - "subject": "Objet", - "subjectPlaceholder": "Ex. Alerte sur $(alert.dataSource)", - "body": "Corps", - "bodyPlaceholder": "Contenu du message. Les gabarits comme $(alert.name) sont interpolés." - }, - "notify": { - "level": "Level", - "message": "Message", - "messagePlaceholder": "Notification text. Templates like $(alert.name) are interpolated." + "status": { + "ACTIVE": "Actif", + "SUSPENDED": "Suspendu", + "TERMINATED": "Résilié" + }, + "support": { + "NONE": "Aucun accès", + "READ": "Accès en lecture", + "FULL": "Accès complet", + "hint": "Accordé par le locataire, pas par vous. Seul son administrateur peut le changer." + }, + "card": { + "edit": "Modifier", + "activate": "Activer", + "deactivate": "Désactiver", + "deletePermanent": "Supprimer définitivement", + "noAccess": "Ce locataire ne vous a pas donné accès.", + "loadingStats": "Lecture…", + "enter": "Entrer" + }, + "stats": { + "users": "Utilisateurs", + "datasources": "Sources", + "openAlerts": "Alertes ouvertes", + "ai": "IA aujourd'hui", + "noLimit": "sans plafond" + }, + "fields": { + "name": "Nom", + "domain": "Domaine", + "domainHint": "Par où ce locataire est joint. Toute requête sur cet hôte entre dans ses données.", + "adminEmail": "E-mail de l'administrateur", + "adminEmailHint": "Il reçoit une invitation pour définir son propre mot de passe.", + "status": "Statut", + "suspendedWarning": "Un locataire suspendu ne peut pas se connecter. Ses données sont conservées.", + "aiLimit": "Plafond de requêtes IA", + "aiLimitHint": "Un plafond opérationnel, par jour. Sans plafond, la consommation compte sur la licence de l'instance.", + "aiLimitToggle": "Plafonner ce locataire" + }, + "create": { + "title": "Nouveau locataire", + "subtitle": "Crée le locataire et invite son premier administrateur.", + "submit": "Créer le locataire" + }, + "edit": { + "title": "Modifier le locataire", + "subtitle": "L'accès support n'est pas ici : seul le locataire peut l'accorder.", + "submit": "Enregistrer" + }, + "terminate": { + "title": "Désactiver ce locataire ?", + "body": "Plus personne chez {{name}} ne pourra se connecter. Les données sont conservées, c'est donc réversible, mais le client est hors ligne dès maintenant.", + "confirmLabel": "Saisissez {{name}} pour confirmer", + "submit": "Désactiver" + }, + "reactivate": { + "title": "Activer ce locataire ?", + "body": "{{name}} pourra se reconnecter. Les données conservées sont restaurées telles quelles.", + "submit": "Activer" + }, + "deletePermanent": { + "title": "Supprimer ce locataire pour toujours ?", + "body": "Toute trace de {{name}} — utilisateurs, sources de données, tableaux de bord, alertes, intégrations — sera effacée. C'est irréversible.", + "confirmLabel": "Saisissez {{name}} pour confirmer", + "submit": "Supprimer définitivement" + }, + "toast": { + "created": "Locataire créé", + "updated": "Locataire mis à jour", + "terminated": "Locataire résilié", + "reactivated": "Locataire réactivé", + "permanentlyDeleted": "Locataire supprimé définitivement", + "domainInUse": "Ce domaine est déjà pris", + "noPermission": "Vous n'avez pas la permission de faire cela", + "notFound": "Locataire introuvable", + "invalidRequest": "Requête invalide", + "operationFailed": "L'opération a échoué" + }, + "switcher": { + "aria": "Switch tenant", + "self": "Default tenant", + "create": "Create tenant" } - } - }, - "executions": { - "search": "Rechercher par ID d'alerte…", - "all": "Toutes", - "loading": "Chargement des exécutions…", - "loadError": "Impossible de charger les exécutions.", - "retry": "Réessayer", - "empty": "Aucune exécution pour l'instant.", - "cols": { - "status": "Statut", - "flow": "Flux", - "command": "Commande / Action", - "agent": "Agent", - "date": "Date", - "retries": "Tentatives", - "node": "Nœud" - }, - "filters": { - "source": "Source", - "allSources": "Toutes les sources" - }, - "manual": "Console interactive" - }, - "executionStatus": { - "WAITING": "En attente", - "PENDING": "En file d'attente", - "EXECUTING": "En cours d'exécution", - "EXECUTED": "Exécuté", - "FAILED": "Échoué", - "DEAD": "Inaccessible" - }, - "executionOrigin": { - "FLOW": "Flux", - "MANUAL": "Manuel" - }, - "nonExecutionCause": { - "AGENT_OFFLINE": "Agent hors ligne", - "AGENT_NOT_FOUND": "Agent introuvable", - "UNKNOWN": "Inconnu" - }, - "kpi": { - "flows": "Total des flux", - "active": "Actifs", - "runs24h": "Exécutions (24 h)", - "failed24h": "Échecs (24 h)" - }, - "neverRun": "jamais", - "create": { - "title": "Nouveau flux", - "modeManual": "Créer manuellement", - "modeAi": "Avec l'IA", - "aiLocked": "Activez SOC-AI et configurez-le pour utiliser ceci.", - "name": "Nom du flux", - "namePlaceholder": "p. ex. Bloquer l'IP en cas d'échecs répétés", - "aiDescriptionLabel": "Que doit faire ce flux ?", - "aiDescriptionPlaceholder": "p. ex. En cas d'alerte critique, rechercher l'IP source dans les menaces et la bloquer sur le pare-feu", - "aiCreate": "Créer avec l'IA", - "manualContinue": "Continuer" - } - }, - "compliance": { - "title": "Compliance", - "subtitle": "Évaluez votre posture face aux frameworks de sécurité — voyez quels contrôles sont respectés et lesquels ne le sont pas.", - "comingSoon": "Bientôt disponible.", - "tabs": { - "frameworks": "Frameworks", - "schedule": "Planification", - "controls": "Contrôles" - }, - "search": "Rechercher des frameworks…", - "refresh": "Refresh", - "loading": "Chargement des frameworks…", - "loadError": "Could not load reports", - "retry": "Réessayer", - "empty": "Aucun framework ne correspond.", - "notEvaluated": "Non évalué", - "controlsCount": "{{n}} contrôles", - "enabledLabel": "Activé", - "runReport": "Exécuter le rapport", - "backToFrameworks": "Retour aux frameworks", - "statusAuto": "Auto (évalué)", - "overrideError": "Impossible de mettre à jour le statut", - "noteError": "Impossible d’enregistrer la note", - "notes": { - "title": "Notes", - "placeholder": "Ajouter une note…", - "save": "Enregistrer", - "cancel": "Annuler" - }, - "reasonModal": { - "title": "Motif requis", - "description": "Indiquez le motif du changement de statut. Il sera enregistré.", - "label": "Motif", - "placeholder": "Expliquez pourquoi vous modifiez le statut de ce contrôle…", - "confirm": "Confirmer le changement", - "cancel": "Annuler" }, - "coverageLabel": "Couverture", - "activityLabel": "Activité", - "evidenceLabel": "Preuve", - "seeMore": "Voir plus", - "seeLess": "Voir moins", - "evaluating": "Évaluation du framework…", - "complianceScore": "Score de conformité", - "generatedAt": "Généré {{date}}", - "reportError": "Impossible de générer le rapport.", - "coverage": "{{n}} règles", - "activity": "{{n}} alertes", - "status": { - "COMPLIANT": "Conforme", - "NON_COMPLIANT": "Non conforme", - "AT_RISK": "À risque", - "NOT_COVERED": "Non couvert", - "OUT_OF_SCOPE": "Hors périmètre", - "PENDING": "En attente", - "label": "Statut", - "NOT_EVALUATED": "Not evaluated" - }, - "toast": { - "toggleError": "Échec du changement d'état du framework", - "reportGenerated": "Rapport généré", - "reportError": "Échec de la génération du rapport" - }, - "schedule": { - "new": "Nouvelle planification", - "loading": "Chargement des planifications…", - "loadError": "Impossible de charger les planifications.", - "empty": "Aucune planification pour l'instant.", - "edit": "Modifier", - "delete": "Supprimer", - "newTitle": "Nouvelle planification", - "editTitle": "Modifier la planification", - "framework": "Framework", - "cadenceLabel": "Cadence", - "cronHint": "Cron à 5 champs (min heure jour mois jourSemaine).", - "recipientsHint": "E-mails séparés par des virgules. Laissez vide pour seulement stocker le snapshot.", - "save": "Enregistrer", - "cancel": "Annuler", - "frameworkRequired": "Le framework est requis", - "cronRequired": "La planification (cron) est requise", - "cadence": { - "daily": "Quotidienne", - "weekly": "Hebdomadaire", - "monthly": "Mensuelle", - "custom": "Personnalisée" - }, - "toast": { - "saved": "Planification enregistrée", - "saveError": "Échec de l'enregistrement de la planification", - "deleted": "Planification supprimée", - "deleteError": "Échec de la suppression de la planification" - }, - "to": "To", - "cc": "Cc", - "toRequired": "At least one recipient is required", - "windowDays": "Reporting window (days)", - "windowDaysShort": "over {{days}}d", - "windowDaysHint": "How far back the report counts. Independent of how often it runs." - }, - "frameworks": { - "new": "Nouveau framework", - "edit": "Modifier", - "createTitle": "Nouveau framework", - "visualTab": "Visuel", - "codeTab": "Code", - "key": "Clé", - "name": "Nom", - "description": "Description", - "source": "Source", - "sections": "Sections", - "sectionKey": "clé de section", - "sectionName": "Nom de la section", - "requirements": "Exigences", - "reqId": "id exig.", - "reqName": "Nom de l'exigence", - "addSection": "Ajouter une section", - "addRequirement": "Ajouter une exigence", - "satisfiedBy": "satisfaite par des contrôles", - "searchControls": "Rechercher des contrôles…", - "noControls": "Aucun contrôle", - "save": "Enregistrer", - "delete": "Supprimer", - "confirmDelete": "Confirmer la suppression", - "cancel": "Annuler", - "yamlError": "Impossible d'appliquer le YAML : {{error}}", - "keyRequired": "La clé est requise", - "nameRequired": "Le nom est requis", - "toast": { - "created": "Framework créé", - "saved": "Framework enregistré", - "saveError": "Échec de l'enregistrement du framework", - "deleted": "Framework supprimé", - "deleteError": "Échec de la suppression du framework" - }, - "createControl": "Créer un nouveau contrôle…", - "createNamed": "Créer le contrôle « {{name}} »…" - }, - "controls": { - "search": "Rechercher des contrôles…", - "allFamilies": "Toutes les familles", - "new": "Nouveau contrôle", - "loading": "Chargement des contrôles…", - "loadError": "Impossible de charger les contrôles.", - "empty": "Aucun contrôle ne correspond.", - "showingOf": "Affichage de {{shown}} sur {{total}}", - "id": "ID", - "name": "Nom", - "family": "Famille", - "familyName": "Famille", - "scope": "Périmètre", - "source": "Source", - "notInLibrary": "Contrôle introuvable dans la bibliothèque", - "scopeOpt": { - "data": "Données", - "governance": "Gouvernance" - }, - "strategy": "Stratégie", - "statement": "Énoncé", - "remediation": "Remédiation", - "checks": "Vérifications", - "checksHint": "Chaque vérification exécute une requête SQL OpenSearch et applique une règle pour décider réussite/échec.", - "checkKey": "clé", - "checkName": "Nom de la vérification", - "rule": { - "MIN_HITS_REQUIRED": "Minimum de résultats requis", - "THRESHOLD_MAX": "Seuil maximum" - }, - "ruleNone": "Aucune règle", - "ruleValue": "valeur", - "addCheck": "Ajouter une vérification", - "createTitle": "Nouveau contrôle", - "visualTab": "Visuel", - "codeTab": "Code", - "save": "Enregistrer", - "delete": "Supprimer", - "confirmDelete": "Confirmer la suppression", - "cancel": "Annuler", - "yamlError": "Impossible d'appliquer le YAML : {{error}}", - "idRequired": "L'ID est requis", - "nameRequired": "Le nom est requis", - "anyDataType": "Any data type", - "addFilter": "Add filter", - "filterField": "log.eventCode", - "filterValue": "value", - "filterValues": "a, b, c", - "toast": { - "created": "Contrôle créé", - "saved": "Contrôle enregistré", - "saveError": "Échec de l'enregistrement du contrôle", - "deleted": "Contrôle supprimé", - "deleteError": "Échec de la suppression du contrôle" - } - }, - "doc": { - "title": "Rapport de conformité", - "print": "Imprimer / PDF", - "controlsEvaluated": "{{n}} contrôles évalués", - "executiveSummary": "Résumé exécutif", - "bySection": "Résultats par section", - "footer": "{{framework}} — Rapport de conformité généré {{date}} · {{brand}}", - "download": "Télécharger le PDF", - "downloadError": "Échec du téléchargement du PDF", - "error": "Impossible de générer le PDF", - "building": "Génération du document…" - }, - "locked": { - "badge": "Enterprise", - "upgrade": "Passer à Enterprise", - "upsell": "Ce framework/contrôle nécessite l'édition Enterprise." - }, - "run": "Run evaluation", - "runError": "Evaluation failed", - "noReportYet": "This framework has not been evaluated yet.", - "window": "window {{from}} → {{to}}", - "scoredOver": "{{compliant}} of {{evaluated}} requirements met · {{total}} in the framework", - "editStale": "Recorded when the engine said {{was}}; it now says {{now}}", - "checkResults": "Check results", - "verdict": "Recorded verdict", - "engineSaid": "engine said", - "hits": "hits", - "noDataFor": "no {{dataType}} data in the window", - "setStatus": "Set status", - "outcome": { - "PASSED": "Passed", - "FAILED": "Failed", - "NOT_APPLICABLE": "No data", - "ERROR": "Error" - }, - "system": "Fourni", - "addNote": "Ajouter une note", - "noteModal": { - "title": "Note", - "description": "Enregistrée dans le rapport. Ne change pas le statut du contrôle.", - "placeholder": "Remédiation en cours — ticket OPS-4412." - }, - "history": { - "title": "Score dans le temps", - "score": "Score de conformité", - "coverage": "Évalués", - "error": "Impossible de charger l’historique" - } - }, - "socAi": { - "title": "Configuration SOC-AI", - "subtitle": "Configurez l'agent IA qui trie les alertes et alimente l'assistant des opérations.", - "section": { - "connection": "Modèle et connexion", - "auth": "Authentification", - "behavior": "Comportement de tri des alertes", - "advanced": "Avancé" - }, - "usage": { - "title": "Utilisation", - "chat": "Complétions de chat (aujourd'hui)", - "unavailable": "L'utilisation n'est pas encore disponible.", - "resetsIn": "Réinitialisation dans {{time}}" - }, - "provider": { - "label": "Fournisseur", - "hint": "Sélectionne le format d'échange. Tout autre fournisseur qu'Anthropic utilise l'API compatible OpenAI." - }, - "model": { - "label": "Modèle", - "hint": "Identifiant du modèle exposé par le fournisseur.", - "customOption": "Modèle personnalisé…", - "customPlaceholder": "Saisissez un identifiant de modèle" - }, - "url": { - "label": "URL de l'API", - "hint": "Laissez vide pour utiliser le point de terminaison par défaut du fournisseur." - }, - "apiKey": { - "label": "Clé d'API", - "hint": "Identifiant envoyé au fournisseur.", - "setHint": "Une clé est enregistrée. Laissez vide pour la conserver." - }, - "authType": { - "label": "Type d'authentification", - "hint": "Comment les identifiants sont envoyés à votre passerelle.", - "options": { - "apiKey": "Clé API", - "bearer": "Bearer", - "customHeaders": "En-têtes personnalisés", - "none": "Aucune" - } - }, - "authHeaderName": { - "label": "Nom de l'en-tête d'authentification", - "hint": "En-tête transportant la clé (par ex. api-key pour Azure)." - }, - "authToken": { - "label": "Jeton Bearer", - "hint": "Identifiant envoyé au fournisseur.", - "setHint": "Un jeton est enregistré. Laissez vide pour le conserver." - }, - "customHeaders": { - "label": "En-têtes personnalisés", - "hint": "En-têtes supplémentaires envoyés à chaque requête. Les valeurs sont chiffrées ; « ***** » conserve celle enregistrée.", - "keyPlaceholder": "Nom de l'en-tête", - "valuePlaceholder": "Valeur", - "addRow": "Ajouter un en-tête", - "remove": "Supprimer l'en-tête" - }, - "maxTokens": { - "label": "Tokens maximum", - "hint": "Nombre maximum de tokens par réponse du LLM." - }, - "maxToolIterations": { - "label": "Itérations d'outils maximum", - "hint": "Limite de la boucle planification -> outil -> observation de l'agent." - }, - "autoAnalyze": { - "label": "Analyser automatiquement les alertes", - "hint": "Trier les alertes entrantes en temps réel." - }, - "allowIncidents": { - "label": "Autoriser la gestion des incidents", - "hint": "L'agent de tri peut créer ou mettre à jour des incidents lorsqu'il juge qu'une alerte le justifie." - }, - "changeAlertStatus": { - "label": "Modifier le statut des alertes", - "hint": "Permettre à l'agent de définir le statut d'une alerte lors du tri." - }, - "automaticIncidentCreation": { - "label": "Créer des incidents", - "hint": "Permettre à l'agent d'ouvrir des incidents à partir des alertes triées." - }, - "allowedWriteTools": { - "label": "Outils d'écriture autorisés", - "hint": "Un nom d'outil MCP par ligne que l'agent de tri peut utiliser (par ex. alerts.update_status). Les notes sont toujours autorisées." - }, - "save": "Enregistrer la configuration", - "saving": "Vérification et enregistrement...", - "saved": "Configuration SOC-AI enregistrée", - "saveError": "Échec de l'enregistrement de la configuration", - "loadError": "Échec du chargement de la configuration", - "modelRequired": "Le modèle est requis", - "applyTags": { - "label": "Appliquer des étiquettes", - "hint": "Permettre à l'agent d'étiqueter les alertes lors du tri." - }, - "note": { - "azure": "Collez l'URL complète de votre point de terminaison de déploiement Azure ; le modèle est le nom de votre déploiement. L'authentification utilise l'en-tête api-key.", - "ollama": "Pointez l'URL vers votre hôte Ollama. Aucune clé d'API n'est nécessaire pour une instance locale.", - "custom": "Tout point de terminaison compatible OpenAI. Définissez l'URL, l'authentification et les en-têtes supplémentaires requis par votre passerelle.", - "threatwinds": "Utilise automatiquement votre licence UTMStack — aucune clé API requise. Facturé via votre abonnement ThreatWinds." - }, - "chat": { - "title": "Assistant SOC", - "dashboardCreateTitle": "Créateur de tableau de bord", - "empty": "Posez n'importe quelle question sur vos alertes, vos détections ou la console — je peux enquêter et agir sur le SIEM.", - "tryPrefix": "Essayez", - "suggestion": "combien d'alertes ouvertes, regroupées par adversaire ?", - "placeholder": "Posez une question…", - "ask": "Demander", - "send": "Envoyer", - "collapse": "Réduire", - "expand": "Agrandir", - "clear": "Effacer la conversation", - "close": "Fermer", - "copy": "Copier", - "copied": "Copié", - "errorGeneric": "Une erreur s'est produite.", - "errorUnreachable": "Impossible de joindre l'assistant.", - "compacting": "Compactage du contexte…", - "dashboardEditTitle": "Éditeur de tableau de bord", - "editingDashboard": "Modification : {{name}}", - "soarEditTitle": "Éditeur de flux SOAR", - "soarCreateTitle": "Créer un flux SOAR", - "editingFlow": "Modification du flux : {{name}}" - }, - "focus": { - "alert": "Alerte", - "incident": "Incident", - "remove": "Ne plus partager avec l'assistant" - }, - "inheritance": { - "inherited": "Suit la valeur par défaut de l'instance. Enregistrer donne à ce locataire sa propre configuration.", - "own": "Ce locataire a sa propre configuration.", - "revert": "Suivre la valeur par défaut de l'instance", - "reverting": "Rétablissement…", - "reverted": "Suit désormais la valeur par défaut de l'instance" - }, - "allowance": { - "title": "Consommation d'IA aujourd'hui", - "ofLimit": "sur {{limit}} requêtes", - "denied": "requêtes — l'IA n'est pas disponible pour ce locataire", - "hint": "Défini par l'exploitant de l'instance. Réinitialisé à minuit UTC." - } - }, - "taggingRules": { - "title": "Règles d'étiquetage", - "subtitle": "Étiqueter automatiquement les alertes qui correspondent aux conditions.", - "new": "Nouvelle règle", - "refresh": "Actualiser", - "empty": "Aucune règle d'étiquetage pour l'instant.", - "loadError": "Impossible de charger les règles d'étiquetage.", - "retry": "Réessayer", - "deleteConfirm": "Supprimer la règle « {{name}} » ? Les futures alertes correspondant à ses conditions ne seront plus étiquetées.", - "toolbar": { - "search": "Rechercher par nom de règle…", - "allTags": "Toutes les étiquettes" - }, - "table": { - "rule": "Règle", - "tags": "Étiquettes", - "conditions": "Conditions", - "modifiedBy": "Modifiée par", - "modifiedDate": "Modifiée" - }, - "drawer": { - "createTitle": "Nouvelle règle d'étiquetage", - "edit": "Modifier", - "delete": "Supprimer", - "save": "Enregistrer", - "create": "Créer", - "cancel": "Annuler" - }, - "form": { - "basics": "Informations de base", - "name": "Nom de la règle", - "namePlaceholder": "par ex. Force brute SSH interne", - "description": "Description", - "descriptionPlaceholder": "Pourquoi cette règle existe et ce qu'elle étiquette.", - "tags": "Étiquettes à appliquer", - "noTags": "Aucune étiquette sélectionnée.", - "addTag": "Ajouter une étiquette", - "removeTag": "Retirer", - "noCatalog": "Aucune étiquette dans le catalogue pour l'instant.", - "createTag": "Créer une étiquette", - "newTagName": "Nom de la nouvelle étiquette", - "conditions": "Conditions (TOUTES doivent correspondre)", - "noConditions": "Au moins une condition est requise.", - "addCondition": "Ajouter une condition", - "removeCondition": "Retirer la condition", - "valuePlaceholder": "Valeur", - "valueListPlaceholder": "Valeurs séparées par des virgules", - "incomplete": "Renseignez le nom de la règle, la description, au moins une étiquette et complétez chaque condition." - }, - "view": { - "description": "Description", - "tags": "Étiquettes", - "conditions": "Conditions", - "audit": "Audit", - "createdBy": "Créée par", - "createdDate": "Créée", - "modifiedBy": "Modifiée par", - "modifiedDate": "Modifiée" - }, - "toast": { - "created": "Règle « {{name}} » créée.", - "updated": "Règle « {{name}} » mise à jour.", - "deleted": "Règle « {{name}} » supprimée.", - "createError": "Échec de la création de la règle.", - "updateError": "Échec de la mise à jour de la règle.", - "deleteError": "Échec de la suppression de la règle." - }, - "deleteTitle": "Supprimer la règle d'étiquetage" - }, - "threatIntel": { - "header": { - "matchedInEnv": "correspondances détectées dans votre environnement", - "export": "Exporter les IOCs", - "exporting": "Exportation…", - "noInstanceIocs": "Aucun indicateur d'instance — affichage de données génériques", - "noInstanceIocsHint": "Aucun indicateur observé dans vos alertes — affichage des données génériques des flux." - }, - "overview": { - "title": "Correspondances IOC", - "totalIndicators": "indicateurs au total", - "families": { - "ip": "IP", - "url": "URL", - "domain": "Domaine", - "signatures": "Signatures" - } - }, - "notConfigured": { - "title": "Threat Intelligence n'est pas configuré", - "body": "Contactez votre administrateur pour connecter une instance Cyber Mantra / ThreatWinds à cet environnement." - }, - "lookup": { - "title": "Rechercher n'importe quel indicateur", - "placeholder": "Collez une IP, domaine, hash, URL ou CVE — nous vérifierons les flux et votre environnement", - "button": "Rechercher", - "busy": "Recherche en cours…" - }, - "tabs": { - "iocs": "IOCs", - "actors": "Acteurs de menace", - "feeds": "Flux", - "analyst": "Analyste IA" - }, - "toolbar": { - "searchPlaceholders": { - "iocs": "Recherchez la valeur IOC, tag, source…", - "actors": "Recherchez acteurs, alias, techniques…", - "feeds": "Recherchez des flux…" - }, - "last24h": "Dernières 24 heures", - "filters": "Filtres", - "refresh": "Actualiser" - }, - "iocs": { - "table": { - "type": "Type", - "indicator": "Indicateur", - "reputation": "Réputation", - "tags": "Tags", - "lastSeen": "Dernière détection" - }, - "empty": "Aucune correspondance IOC.", - "loadingMore": "Chargement…", - "loadedProgress": "{{loaded}} sur {{total}} chargés. Défilez pour plus.", - "endOfResults": "Fin des résultats ({{loaded}} sur {{total}})." - }, - "drawer": { - "loading": "Chargement…", - "accuracy": "Précision :", - "actions": { - "block": "Bloquer en périphérie", - "viewEvents": "Afficher les événements correspondants", - "externalLookup": "Recherche externe", - "trackCampaign": "Suivre la campagne", - "viewIocs": "Afficher les IOCs correspondants", - "mitre": "MITRE ATT&CK" - }, - "sections": { - "timeline": "Chronologie", - "networkOrigin": "Réseau / origine", - "associationsWithCount": "Associations ({{count}})", - "geolocationsWithCount": "Géolocalisations ({{count}})", - "about": "À propos", - "activity": "Activité" - }, - "fields": { - "firstSeen": "Première détection", - "lastSeen": "Dernière détection", - "country": "Pays", - "city": "Ville", - "aso": "ASO", - "asn": "ASN", - "reputation": "Réputation", - "accuracy": "Précision", - "current": "Actuel", - "best": "Meilleur", - "worst": "Pire" - }, - "aiBrief": "Résumé IA", - "noDescription": "Aucune description disponible pour cet indicateur.", - "lastObserved": "Dernière observation {{when}}." - }, - "actors": { - "empty": "Aucun acteur trouvé." - }, - "feeds": { - "empty": "Aucun flux configuré.", - "table": { - "name": "Flux", - "type": "Type", - "accuracy": "Précision", - "header": "Flux", - "format": "Format" - }, - "download": "Télécharger le flux", - "checksum": "Somme de contrôle" - }, - "entityTypes": { - "ip": "IP", - "hostname": "Hôte", - "domain": "Domaine", - "url": "URL", - "hash": "Hash", - "cve": "CVE", - "threat": "Menace", - "entity": "Entité" - }, - "reputation": { - "alarming": "Alarmant", - "suspicious": "Suspect", - "indefinable": "Indéfini", - "fair": "Acceptable", - "trustworthy": "De confiance" - }, - "feedAccuracy": { - "level1": "Niveau 1", - "level2": "Niveau 2", - "level3": "Niveau 3" - }, - "triage": { - "title": "Triage", - "subtitle": "Paste indicators, get verdicts", - "input": "Indicators", - "placeholder": "Paste IPs, domains, URLs or hashes — one per line, or comma separated.\nDefanged values (1.2.3[.]4, hxxp://) are accepted.", - "run": "Triage", - "stop": "Stop", - "reset": "Clear", - "parsed": "{{count}} unique indicators", - "capped": "Capped at {{max}} per run.", - "progress": "{{done}} of {{total}}", - "empty": "Paste indicators above to begin.", - "indicator": "Indicator", - "type": "Type", - "verdict": "Verdict", - "reputation": "Rep", - "accuracy": "Acc", - "tags": "Tags", - "lastSeen": "Last seen", - "exportCsv": "Export CSV", - "exportStix": "Export STIX", - "stixNote": "STIX export includes malicious and suspicious rows only.", - "open": "Open", - "notConfigured": "Threat intelligence is not configured — triage needs an upstream ThreatWinds instance.", - "summary": "Summary", - "v.malicious": "Malicious", - "v.suspicious": "Suspicious", - "v.benign": "Benign", - "v.unknown": "Unknown", - "v.notFound": "Not found", - "v.invalid": "Unrecognised" - }, - "report": { - "title": "Signaler", - "subtitle": "Publier un indicateur dans le graphe ThreatWinds", - "submit": "Signaler l'indicateur", - "submitting": "Signalement…", - "error": { - "generic": "Impossible de soumettre l'indicateur. Réessayez." - }, - "value": { - "label": "Indicateur", - "placeholder": "IP, domaine, URL, hachage ou adresse e-mail" - }, - "type": { - "label": "Type", - "placeholder": "Déduit de la valeur", - "inferred": "Déduit : {{type}}", - "inferenceFailed": "Aucun type n'a pu être déduit de cette valeur. Choisissez-en un dans la liste ou saisissez-le.", - "unknown": "« {{type}} » n'est pas un type d'entité. Choisissez-en un dans la liste." - }, - "tags": { - "label": "Étiquettes", - "placeholder": "phishing, vol-de-credentials" - }, - "description": { - "label": "Notes" - }, - "reputation": { - "legend": "Réputation", - "hint": "Laissez vide si vous n'avez pas de verdict.", - "alarming": "Alarmant", - "worrying": "Préoccupant", - "concerning": "Suspect", - "indefinable": "Indéfinissable", - "adequate": "Suffisant", - "good": "Bon", - "exceptional": "Excellent" - }, - "associations": { - "legend": "Indicateurs liés", - "add": "Ajouter un indicateur lié", - "remove": "Supprimer", - "valuePlaceholder": "Valeur liée", - "typePlaceholder": "Type (facultatif)", - "modeLabel": "Relation", - "mode": { - "association": "Lié à", - "aggregation": "Fait partie de" - }, - "visibilityConflict": "N'appartient à aucun groupe de visibilité commun avec l'indicateur ci-dessus. La soumission entière serait rejetée." - }, - "attributes": { - "legend": "Détails", - "hint": "Facultatif. Les champs vides ne sont pas soumis.", - "invalidHex": "{{length}} caractères hexadécimaux attendus.", - "invalidHexAny": "Caractères hexadécimaux uniquement.", - "invalidNumber": "Un nombre est attendu." - }, - "correlate": { - "legend": "Corréler", - "hint": "Chaque attribut coché est publié comme entité distincte, liée à celle-ci.", - "count_one": "Crée {{count}} entité liée.", - "count_other": "Crée {{count}} entités liées." - }, - "scan": { - "notice": "Signaler cela met également une analyse de la cible en file d'attente." - }, - "receipt": { - "title": "Soumis", - "noVerdict": "Aucun verdict émis", - "skipped": "Non soumis, aucun type n'a pu être déduit", - "pending": "En attente que l'indicateur apparaisse dans le corpus…", - "live": "Présent dans le corpus — voir l'entité", - "processing": "Toujours en cours de traitement. Il apparaîtra quand l'ingestion sera à jour.", - "another": "Signaler un autre" - }, - "visibility": { - "legend": "Visible à" - }, - "example": "Essayer un exemple" - } - }, - "playground": { - "titleFilter": "Tester le pipeline", - "titleRule": "Tester la règle", - "noDataTypes": "Aucun type de données n'est encore attribué à ce pipeline — ajoutez-en un pour le tester.", - "dataTypeLabel": "Type de données", - "dataTypePlaceholder": "Aucun type de données disponible", - "dataTypeSingleHint": "Ce pipeline n'a qu'un seul type de données — ajoutez-en d'autres pour pouvoir choisir.", - "rawLogLabel": "Journal brut", - "rawLogPlaceholder": "Collez une ligne de journal d'exemple…", - "rawLogCounter": "{{chars}} car. · {{kb}} Ko", - "rawLogTooLarge": "Ce journal dépasse la limite de 1 Mo — réduisez-le avant d'exécuter le test.", - "run": { - "label": "Exécuter", - "running": "Test en cours…", - "waitHint": "Cela peut prendre jusqu'à 15 secondes pendant que le pipeline traite le journal." - }, - "errors": { - "busy": "Le playground exécute déjà un autre test — veuillez réessayer sous peu.", - "timeout": "Le test a expiré — cela signifie généralement que le type de données sélectionné ne correspond pas au format du journal.", - "validation": "La requête est invalide — vérifiez le journal brut et le contenu du pipeline.", - "server": "Le playground n'a pas pu terminer le test — veuillez réessayer." - }, - "notices": { - "geo": "Le plugin de géolocalisation n'est pas disponible dans cette version allégée du test de filtres et de règles.", - "correlation": "Les règles qui référencent des événements antérieurs via les clauses afterEvent ou correlation nécessitent que des événements correspondants existent déjà dans le système pour que l'alerte testée se déclenche." - }, - "result": { - "label": "Résultat analysé", - "empty": "Exécutez un test pour voir ici l'événement analysé.", - "loading": "En attente de l'événement analysé…", - "tabs": { - "fields": "Champs", - "json": "JSON" - }, - "fieldsCount_one": "{{count}} champ", - "fieldsCount_other": "{{count}} champs", - "copy": "Copier", - "copied": "Copié", - "elapsed": "Analysé en {{time}}", - "elapsedHint": "Temps entre Exécuter et le résultat analysé", - "searchPlaceholder": "Rechercher des champs…", - "noMatch": "Aucun champ ne correspond à votre recherche." - }, - "alerts": { - "label": "Alertes", - "empty": "Exécutez un test pour voir ici les alertes déclenchées.", - "none": "Aucune alerte n'a été déclenchée.", - "count_one": "{{count}} alerte", - "count_other": "{{count}} alertes" - }, - "title": "Test pipeline" - }, - "tenants": { - "title": "Locataires", - "new": "Nouveau locataire", - "subtitle": "Chaque client de cette instance, ce qu'il détient et ce qu'il vous laisse voir.", - "searchPlaceholder": "Rechercher par nom ou domaine…", - "loading": "Chargement des locataires…", - "loadFailed": "Impossible de charger les locataires.", - "retry": "Réessayer", - "none": "Aucun locataire pour le moment.", - "noSearchMatch": "Aucun locataire ne correspond à la recherche.", - "cancel": "Annuler", - "saving": "Enregistrement…", - "chips": { - "total": "locataires", - "active": "actifs", - "readable": "accessibles" - }, - "status": { - "ACTIVE": "Actif", - "SUSPENDED": "Suspendu", - "TERMINATED": "Résilié" - }, - "support": { - "NONE": "Aucun accès", - "READ": "Accès en lecture", - "FULL": "Accès complet", - "hint": "Accordé par le locataire, pas par vous. Seul son administrateur peut le changer." - }, - "card": { - "edit": "Modifier", - "activate": "Activer", - "deactivate": "Désactiver", - "deletePermanent": "Supprimer définitivement", - "noAccess": "Ce locataire ne vous a pas donné accès.", - "loadingStats": "Lecture…", - "enter": "Entrer" - }, - "stats": { - "users": "Utilisateurs", - "datasources": "Sources", - "openAlerts": "Alertes ouvertes", - "ai": "IA aujourd'hui", - "noLimit": "sans plafond" - }, - "fields": { - "name": "Nom", - "domain": "Domaine", - "domainHint": "Par où ce locataire est joint. Toute requête sur cet hôte entre dans ses données.", - "adminEmail": "E-mail de l'administrateur", - "adminEmailHint": "Il reçoit une invitation pour définir son propre mot de passe.", - "status": "Statut", - "suspendedWarning": "Un locataire suspendu ne peut pas se connecter. Ses données sont conservées.", - "aiLimit": "Plafond de requêtes IA", - "aiLimitHint": "Un plafond opérationnel, par jour. Sans plafond, la consommation compte sur la licence de l'instance.", - "aiLimitToggle": "Plafonner ce locataire" - }, - "create": { - "title": "Nouveau locataire", - "subtitle": "Crée le locataire et invite son premier administrateur.", - "submit": "Créer le locataire" - }, - "edit": { - "title": "Modifier le locataire", - "subtitle": "L'accès support n'est pas ici : seul le locataire peut l'accorder.", - "submit": "Enregistrer" - }, - "terminate": { - "title": "Désactiver ce locataire ?", - "body": "Plus personne chez {{name}} ne pourra se connecter. Les données sont conservées, c'est donc réversible, mais le client est hors ligne dès maintenant.", - "confirmLabel": "Saisissez {{name}} pour confirmer", - "submit": "Désactiver" - }, - "reactivate": { - "title": "Activer ce locataire ?", - "body": "{{name}} pourra se reconnecter. Les données conservées sont restaurées telles quelles.", - "submit": "Activer" - }, - "deletePermanent": { - "title": "Supprimer ce locataire pour toujours ?", - "body": "Toute trace de {{name}} — utilisateurs, sources de données, tableaux de bord, alertes, intégrations — sera effacée. C'est irréversible.", - "confirmLabel": "Saisissez {{name}} pour confirmer", - "submit": "Supprimer définitivement" - }, - "toast": { - "created": "Locataire créé", - "updated": "Locataire mis à jour", - "terminated": "Locataire résilié", - "reactivated": "Locataire réactivé", - "permanentlyDeleted": "Locataire supprimé définitivement", - "domainInUse": "Ce domaine est déjà pris", - "noPermission": "Vous n'avez pas la permission de faire cela", - "notFound": "Locataire introuvable", - "invalidRequest": "Requête invalide", - "operationFailed": "L'opération a échoué" - }, - "switcher": { - "aria": "Switch tenant", - "self": "Default tenant", - "create": "Create tenant" - } - }, - "supportAccess": { - "title": "Accès support", - "intro": "Celui qui exploite cette instance ne peut pas regarder dans vos données sans votre accord. Rien n'est accordé par défaut, et vous pouvez le retirer à tout moment.", - "loading": "Chargement…", - "loadFailed": "Impossible de lire le réglage actuel.", - "retry": "Réessayer", - "currentBadge": "actuel", - "save": "Enregistrer", - "saving": "Enregistrement…", - "levels": { - "NONE": { - "name": "Aucun accès", - "desc": "L'exploitant voit que votre locataire existe, rien de plus. Toute requête vers vos données est refusée." - }, - "READ": { - "name": "Lecture seule", - "desc": "L'exploitant peut consulter vos alertes, vos logs et votre configuration pour vous aider. Il ne peut rien modifier : toute écriture est refusée, quel que soit son propre rôle." - }, - "FULL": { - "name": "Accès complet", - "desc": "L'exploitant peut agir dans votre locataire en tant qu'administrateur : configuration, utilisateurs et flux de réponse." - } - }, - "fullWarning": "L'accès complet lui permet de modifier des choses en votre nom. Accordez-le le temps d'une intervention, puis revenez en arrière.", - "revokeNote": "Tout ce que l'exploitant fait ici est consigné dans votre journal d'audit.", - "toast": { - "granted": "Accès support mis à jour", - "revoked": "Accès support retiré", - "forbidden": "Seul un administrateur de ce locataire peut changer cela", - "invalid": "Requête invalide", - "failed": "Impossible d'enregistrer la modification" - } - }, - "supportSession": { - "inside": "Vous travaillez à l’intérieur de {{name}}", - "readOnly": "lecture seule — les écritures sont refusées", - "full": "accès complet — les changements ici sont réels", - "leave": "Quitter" - }, - "platformBroadcast": { - "button": "Appliquer à tous les locataires", - "action": { - "create": "Diffuser la création de {{resource}}", - "update": "Diffuser la mise à jour de {{resource}}", - "delete": "Diffuser la suppression de {{resource}}", - "toggle": "Diffuser le basculement de {{resource}}", - "enable": "Diffuser l'activation de {{resource}}", - "activate": "Diffuser l'activation de {{resource}}", - "test": "Diffuser le test {{resource}}", - "upload": "Diffuser l'actif {{resource}}" - }, - "resource": { - "pipeline": "pipeline", - "correlationRule": "règle de corrélation", - "soarFlow": "flux SOAR", - "framework": "cadre", - "control": "contrôle", - "smtp": "SMTP", - "idp": "fournisseur d'identité", - "branding": "marque" - }, - "warning": { - "title": "Cette action s'exécutera sur chaque locataire sélectionné.", - "body": "Les échecs par locataire sont signalés après l'exécution et ne sont pas annulés." - }, - "allTenants": "Appliquer à tous les locataires", - "excludesDefault": "Le locataire de la plateforme est exclu de cette action.", - "searchPlaceholder": "Rechercher des locataires…", - "loading": "Chargement des locataires…", - "empty": "Aucun locataire ne correspond.", - "targetCount": "Ciblera {{count}} locataire(s).", - "platformTenant": "plateforme", - "confirm": "Appliquer à {{count}} locataire(s)", - "result": { - "succeeded": "Réussi", - "noneSucceeded": "Aucun locataire n'a réussi.", - "failed": "Échoué", - "noneFailed": "Aucun échec." - } - }, - "tiAnalyst": { - "console": { - "subtitle": "Espace analyste", - "model": "Modèle", - "resizeResults": "Redimensionner le panneau de résultats", - "resizeHint": "Glisser pour redimensionner · double-clic pour réinitialiser" - }, - "conv": { - "title": "Conversations", - "allConversations": "Toutes les conversations", - "empty": "Aucune conversation pour l'instant.", - "new": "Nouvelle conversation", - "newTitle": "Titre de la conversation", - "selectPrompt": "Sélectionnez une conversation, ou commencez-en une.", - "running": "en cours", - "delete": "Supprimer {{title}}", - "unread_one": "{{count}} message non lu", - "unread_other": "{{count}} messages non lus", - "transcript": "Transcription de la conversation" - }, - "agent": { - "placeholder": "Investiguer un indicateur…", - "ask": "Demander à l'agent analyste", - "intro": "Posez une question sur n'importe quel indicateur. L'agent interroge ThreatWinds directement et montre son travail.", - "send": "Envoyer", - "stop": "Arrêter", - "thinking": "réflexion…", - "suggestionInvestigate": "Investiguez 8.8.8.8 et dites-moi si c'est malveillant", - "suggestionInfrastructure": "Quelles infrastructures sont liées à google.com ?", - "suggestionCounts": "Montrez-moi combien d'entités existent par type" + "supportAccess": { + "title": "Accès support", + "intro": "Celui qui exploite cette instance ne peut pas regarder dans vos données sans votre accord. Rien n'est accordé par défaut, et vous pouvez le retirer à tout moment.", + "loading": "Chargement…", + "loadFailed": "Impossible de lire le réglage actuel.", + "retry": "Réessayer", + "currentBadge": "actuel", + "save": "Enregistrer", + "saving": "Enregistrement…", + "levels": { + "NONE": { + "name": "Aucun accès", + "desc": "L'exploitant voit que votre locataire existe, rien de plus. Toute requête vers vos données est refusée." + }, + "READ": { + "name": "Lecture seule", + "desc": "L'exploitant peut consulter vos alertes, vos logs et votre configuration pour vous aider. Il ne peut rien modifier : toute écriture est refusée, quel que soit son propre rôle." + }, + "FULL": { + "name": "Accès complet", + "desc": "L'exploitant peut agir dans votre locataire en tant qu'administrateur : configuration, utilisateurs et flux de réponse." + } + }, + "fullWarning": "L'accès complet lui permet de modifier des choses en votre nom. Accordez-le le temps d'une intervention, puis revenez en arrière.", + "revokeNote": "Tout ce que l'exploitant fait ici est consigné dans votre journal d'audit.", + "toast": { + "granted": "Accès support mis à jour", + "revoked": "Accès support retiré", + "forbidden": "Seul un administrateur de ce locataire peut changer cela", + "invalid": "Requête invalide", + "failed": "Impossible d'enregistrer la modification" + } }, - "canvas": { - "title": "Résultats", - "empty": "Les résultats de cette conversation apparaissent ici.", - "tile": "Aligner", - "closeAll": "Tout fermer", - "pinOut": "Ouvrir {{title}} en panneau", - "loading": "chargement…", - "failed": "impossible de charger", - "noRelations": "aucune entité liée", - "noGeo": "pas de géolocalisation enregistrée", - "noResults": "aucune correspondance", - "matches": "{{total}} correspondances", - "panelName": "{{title}} — {{kind}}", - "movePanel": "Déplacer {{title}}", - "resizePanel": "Redimensionner {{title}}", - "closePanel": "Fermer {{title}}", - "collapse": "Réduire {{title}}", - "expand": "Agrandir {{title}}", - "kind": { - "entity": "dossier", - "graph": "relations", - "geo": "géolocalisation", - "search": "recherche" - } + "supportSession": { + "inside": "Vous travaillez à l’intérieur de {{name}}", + "readOnly": "lecture seule — les écritures sont refusées", + "full": "accès complet — les changements ici sont réels", + "leave": "Quitter" + }, + "platformBroadcast": { + "button": "Appliquer à tous les locataires", + "action": { + "create": "Diffuser la création de {{resource}}", + "update": "Diffuser la mise à jour de {{resource}}", + "delete": "Diffuser la suppression de {{resource}}", + "toggle": "Diffuser le basculement de {{resource}}", + "enable": "Diffuser l'activation de {{resource}}", + "activate": "Diffuser l'activation de {{resource}}", + "test": "Diffuser le test {{resource}}", + "upload": "Diffuser l'actif {{resource}}" + }, + "resource": { + "pipeline": "pipeline", + "correlationRule": "règle de corrélation", + "soarFlow": "flux SOAR", + "framework": "cadre", + "control": "contrôle", + "smtp": "SMTP", + "idp": "fournisseur d'identité", + "branding": "marque" + }, + "warning": { + "title": "Cette action s'exécutera sur chaque locataire sélectionné.", + "body": "Les échecs par locataire sont signalés après l'exécution et ne sont pas annulés." + }, + "allTenants": "Appliquer à tous les locataires", + "excludesDefault": "Le locataire de la plateforme est exclu de cette action.", + "searchPlaceholder": "Rechercher des locataires…", + "loading": "Chargement des locataires…", + "empty": "Aucun locataire ne correspond.", + "targetCount": "Ciblera {{count}} locataire(s).", + "platformTenant": "plateforme", + "confirm": "Appliquer à {{count}} locataire(s)", + "result": { + "succeeded": "Réussi", + "noneSucceeded": "Aucun locataire n'a réussi.", + "failed": "Échoué", + "noneFailed": "Aucun échec." + } }, - "graph": { - "nodes_one": "{{count}} nœud", - "nodes_other": "{{count}} nœuds", - "edges_one": "{{count}} arête", - "edges_other": "{{count}} arêtes", - "clickToPivot": "clic pour pivoter", - "malicious": "malveillant", - "unknown": "inconnu", - "benign": "bénin" + "tiAnalyst": { + "console": { + "subtitle": "Espace analyste", + "model": "Modèle", + "resizeResults": "Redimensionner le panneau de résultats", + "resizeHint": "Glisser pour redimensionner · double-clic pour réinitialiser" + }, + "conv": { + "title": "Conversations", + "allConversations": "Toutes les conversations", + "empty": "Aucune conversation pour l'instant.", + "new": "Nouvelle conversation", + "newTitle": "Titre de la conversation", + "selectPrompt": "Sélectionnez une conversation, ou commencez-en une.", + "running": "en cours", + "delete": "Supprimer {{title}}", + "unread_one": "{{count}} message non lu", + "unread_other": "{{count}} messages non lus", + "transcript": "Transcription de la conversation" + }, + "agent": { + "placeholder": "Investiguer un indicateur…", + "ask": "Demander à l'agent analyste", + "intro": "Posez une question sur n'importe quel indicateur. L'agent interroge ThreatWinds directement et montre son travail.", + "send": "Envoyer", + "stop": "Arrêter", + "thinking": "réflexion…", + "suggestionInvestigate": "Investiguez 8.8.8.8 et dites-moi si c'est malveillant", + "suggestionInfrastructure": "Quelles infrastructures sont liées à google.com ?", + "suggestionCounts": "Montrez-moi combien d'entités existent par type" + }, + "canvas": { + "title": "Résultats", + "empty": "Les résultats de cette conversation apparaissent ici.", + "tile": "Aligner", + "closeAll": "Tout fermer", + "pinOut": "Ouvrir {{title}} en panneau", + "loading": "chargement…", + "failed": "impossible de charger", + "noRelations": "aucune entité liée", + "noGeo": "pas de géolocalisation enregistrée", + "noResults": "aucune correspondance", + "matches": "{{total}} correspondances", + "panelName": "{{title}} — {{kind}}", + "movePanel": "Déplacer {{title}}", + "resizePanel": "Redimensionner {{title}}", + "closePanel": "Fermer {{title}}", + "collapse": "Réduire {{title}}", + "expand": "Agrandir {{title}}", + "kind": { + "entity": "dossier", + "graph": "relations", + "geo": "géolocalisation", + "search": "recherche" + } + }, + "graph": { + "nodes_one": "{{count}} nœud", + "nodes_other": "{{count}} nœuds", + "edges_one": "{{count}} arête", + "edges_other": "{{count}} arêtes", + "clickToPivot": "clic pour pivoter", + "malicious": "malveillant", + "unknown": "inconnu", + "benign": "bénin" + }, + "entity": { + "reputation": "Réputation", + "accuracy": "Précision", + "worst": "Pire", + "best": "Meilleure", + "relations": "Graphe de relations", + "history": "Historique", + "geolocations": "Géolocalisations", + "associations": "Associations", + "radius": "r={{radius}}m", + "askAgentBtn": "Demander à l'agent", + "askAgent": "Évaluez {{type}} {{value}} (entité id {{id}}). Est-ce une menace ?" + }, + "tool": { + "querying": "interrogation…", + "notRetained": "Résultat non conservé.", + "expand": "Afficher la requête et le résultat", + "collapse": "Masquer la requête et le résultat", + "noIntel": "« {{value}} » n'a aucune information de menace enregistrée.", + "noMatches": "Aucune correspondance.", + "matches": "{{items}} correspondances pour « {{query}} »", + "more": "+{{count}} de plus", + "reported": "Signale au corpus ThreatWinds partage. L ingestion est asynchrone, non immediatement rechercheable.", + "skippedAssociations": "Non enregistre (type non inferable) : {{values}}" + } }, - "entity": { - "reputation": "Réputation", - "accuracy": "Précision", - "worst": "Pire", - "best": "Meilleure", - "relations": "Graphe de relations", - "history": "Historique", - "geolocations": "Géolocalisations", - "associations": "Associations", - "radius": "r={{radius}}m", - "askAgentBtn": "Demander à l'agent", - "askAgent": "Évaluez {{type}} {{value}} (entité id {{id}}). Est-ce une menace ?" + "threatwinds": { + "title": "Intégration ThreatWinds", + "subtitle": "Partagez les incidents de cette instance avec le flux communautaire ThreatWinds.", + "feeds": "Activer les flux", + "feedsHint": "Quand activé, les événements sont vérifiés contre les flux d'intelligence ThreatWinds.", + "contribute": "Contribuer des incidents", + "contributeHint": "Quand activé, les incidents de cette instance sont envoyés à ThreatWinds.", + "loading": "Chargement du statut de l'intégration…", + "failed": "Impossible de charger le statut de l'intégration ThreatWinds.", + "retry": "Réessayer", + "toast": { + "enabled": "Contribution activée", + "disabled": "Contribution désactivée", + "failed": "Impossible de mettre à jour le réglage de contribution" + } }, - "tool": { - "querying": "interrogation…", - "notRetained": "Résultat non conservé.", - "expand": "Afficher la requête et le résultat", - "collapse": "Masquer la requête et le résultat", - "noIntel": "« {{value}} » n'a aucune information de menace enregistrée.", - "noMatches": "Aucune correspondance.", - "matches": "{{items}} correspondances pour « {{query}} »", - "more": "+{{count}} de plus", - "reported": "Signale au corpus ThreatWinds partage. L ingestion est asynchrone, non immediatement rechercheable.", - "skippedAssociations": "Non enregistre (type non inferable) : {{values}}" - } - }, - "threatwinds": { - "title": "Intégration ThreatWinds", - "subtitle": "Partagez les incidents de cette instance avec le flux communautaire ThreatWinds.", - "feeds": "Activer les flux", - "feedsHint": "Quand activé, les événements sont vérifiés contre les flux d'intelligence ThreatWinds.", - "contribute": "Contribuer des incidents", - "contributeHint": "Quand activé, les incidents de cette instance sont envoyés à ThreatWinds.", - "loading": "Chargement du statut de l'intégration…", - "failed": "Impossible de charger le statut de l'intégration ThreatWinds.", - "retry": "Réessayer", - "toast": { - "enabled": "Contribution activée", - "disabled": "Contribution désactivée", - "failed": "Impossible de mettre à jour le réglage de contribution" - } - }, - "liveOps": { - "header": "Opérations en direct", - "live": "EN DIRECT", - "replay": "LECTURE", - "statLastHour": "Dernière heure", - "statHigh": "Hautes", - "statOpen": "Ouvertes", - "statAttackers": "Auteurs d'attaques", - "listTitle": "Alertes", - "listShown": "{{count}} affichées", - "listShow": "Afficher la liste des alertes", - "listHide": "Masquer la liste", - "agoJust": "à l'instant", - "agoMin": "il y a {{count}} min", - "agoH": "il y a {{count}} h", - "more": "Plus", - "less": "Moins", - "loading": "Chargement des alertes…", - "error": "Impossible de charger les alertes : {{msg}}", - "empty": "Aucune alerte dans le magasin.", - "onStage": "À l'écran", - "hideDetails": "Masquer ce panneau", - "showDetails": "Afficher les détails", - "inIncident": "Dans un incident", - "openInAlerts": "Ouvrir dans Alertes", - "involved": "Impliqués", - "askSocAi": "Demander à SOC-AI", - "askExplain": "Explique cette attaque et dis-moi quoi faire ensuite", - "askFp": "Est-ce un faux positif ?", - "askAttacker": "Qu'a encore fait cet attaquant ?", - "timCount": "{{count}} alertes sur la dernière {{range}}", - "timPrev": "Alerte précédente", - "timNext": "Alerte suivante", - "timReplay": "Lire la fenêtre", - "timStop": "Arrêter la lecture", - "timLive": "EN DIRECT", - "timNow": "maintenant", - "kb": { - "bruteForce": "Force brute", - "outbound": "Connexion à une destination malveillante", - "lateral": "Déplacement latéral", - "malware": "Exécution malveillante sur un hôte", - "webAttack": "Ataque web", - "travel": "Voyage impossible", - "scan": "Scan de ports", - "cloud": "Modification risquée dans le cloud", - "generic": "Détection", - "ransomware": "Rançlogiciel sur un hôte", - "persistence": "Mécanisme de persistance", - "exfil": "Exfiltration de données", - "defenseEvasion": "Évitement des défenses", - "privEsc": "Élévation de privilèges", - "userExec": "Utilisateur ouvre un fichier malveillant", - "softwareDeploy": "Logiciel poussé vers un hôte", - "phishing": "E-mail de phishing ouvert", - "processInjection": "Code injecté dans un processus", - "credDump": "Identifiants volés", - "dataDestruction": "Données détruites", - "toolDownload": "Outil téléchargé et exécuté", - "c2tunnel": "C2 à travers un tunnel", - "iocMatch": "IOC menaces détecté", - "perimeterDetect": "Détection périmètre/IDS", - "accountChange": "Changement de compte ou stratégie", - "kerberosTicket": "Abus de billets Kerberos", - "powershellAbuse": "Abus de scripting", - "reverseShell": "Shell inverse", - "vmEscape": "Évasion VM/hyperviseur" + "liveOps": { + "header": "Opérations en direct", + "live": "EN DIRECT", + "replay": "LECTURE", + "statLastHour": "Dernière heure", + "statHigh": "Hautes", + "statOpen": "Ouvertes", + "statAttackers": "Auteurs d'attaques", + "listTitle": "Alertes", + "listShown": "{{count}} affichées", + "listShow": "Afficher la liste des alertes", + "listHide": "Masquer la liste", + "agoJust": "à l'instant", + "agoMin": "il y a {{count}} min", + "agoH": "il y a {{count}} h", + "more": "Plus", + "less": "Moins", + "loading": "Chargement des alertes…", + "error": "Impossible de charger les alertes : {{msg}}", + "empty": "Aucune alerte dans le magasin.", + "onStage": "À l'écran", + "hideDetails": "Masquer ce panneau", + "showDetails": "Afficher les détails", + "inIncident": "Dans un incident", + "openInAlerts": "Ouvrir dans Alertes", + "involved": "Impliqués", + "askSocAi": "Demander à SOC-AI", + "askExplain": "Explique cette attaque et dis-moi quoi faire ensuite", + "askFp": "Est-ce un faux positif ?", + "askAttacker": "Qu'a encore fait cet attaquant ?", + "timCount": "{{count}} alertes sur la dernière {{range}}", + "timPrev": "Alerte précédente", + "timNext": "Alerte suivante", + "timReplay": "Lire la fenêtre", + "timStop": "Arrêter la lecture", + "timLive": "EN DIRECT", + "timNow": "maintenant", + "kb": { + "bruteForce": "Force brute", + "outbound": "Connexion à une destination malveillante", + "lateral": "Déplacement latéral", + "malware": "Exécution malveillante sur un hôte", + "webAttack": "Ataque web", + "travel": "Voyage impossible", + "scan": "Scan de ports", + "cloud": "Modification risquée dans le cloud", + "generic": "Détection", + "ransomware": "Rançlogiciel sur un hôte", + "persistence": "Mécanisme de persistance", + "exfil": "Exfiltration de données", + "defenseEvasion": "Évitement des défenses", + "privEsc": "Élévation de privilèges", + "userExec": "Utilisateur ouvre un fichier malveillant", + "softwareDeploy": "Logiciel poussé vers un hôte", + "phishing": "E-mail de phishing ouvert", + "processInjection": "Code injecté dans un processus", + "credDump": "Identifiants volés", + "dataDestruction": "Données détruites", + "toolDownload": "Outil téléchargé et exécuté", + "c2tunnel": "C2 à travers un tunnel", + "iocMatch": "IOC menaces détecté", + "perimeterDetect": "Détection périmètre/IDS", + "accountChange": "Changement de compte ou stratégie", + "kerberosTicket": "Abus de billets Kerberos", + "powershellAbuse": "Abus de scripting", + "reverseShell": "Shell inverse", + "vmEscape": "Évasion VM/hyperviseur" + }, + "replayTip": "Rejouer toutes les alertes de cette fenêtre dans l'ordre", + "liveTip": "Suivre les nouvelles alertes à mesure qu'elles arrivent", + "playAgain": "Rejouer cette alerte", + "alertAt": "{{name}} à {{time}}", + "netInternet": "Internet", + "netInternal": "Réseau interne", + "scUser": "utilisateur : {{account}}", + "scWrongPassword": "✕ mauvais mot de passe", + "scSignedIn": "✓ connecté", + "scSignedInAs": "connecté en tant que {{account}}", + "scFailedSignins": "Échecs de connexion", + "scBlocked": "🛡 {{name}} bloqué", + "scSessionAs": "session en tant que {{account}}", + "scHost": "Hôte · {{name}}", + "scFiles": "Documents", + "scBackups": "Copies d’ombre", + "scRansomNote": "🔒 NOTE DE RANÇON", + "scShadows": "✕ copies d’ombre supprimées", + "scPersist": "Persistance", + "scReboot": "survit aux redémarrages — porte dérobée installée", + "scCloud": "Stockage externe", + "scChunk": "données", + "scExfilBytes": "Données exfiltrées", + "scProcessTree": "Arbre de processus", + "scDns": "DNS ? {{host}}", + "scThreatIntel": "Intel menaces : Alarmant (-3)", + "scConnDropped": "✕ connexion interrompue", + "scPortsProbed": "Ports sondés", + "scSignIn": "✓ connexion", + "scKmInMin": "{{km}} km en {{min}} min", + "scAbroad": "à l'étranger", + "scDropped": "{{status}} bloqué", + "scBeacon": "balise", + "capBrute0": "{{name}}{{sub}} commence à deviner les mots de passe contre {{where}}.", + "capBruteVpn": "le VPN sur {{name}}", + "capBrute1": "{{attempts}} échecs de connexion en {{minutes}} minutes, en faisant tourner {{count}} noms de compte.", + "capBrute2": "Une connexion en tant que {{account}} réussit juste après les échecs : le mot de passe a été deviné.", + "capBrute3": "Corrélation des échecs entre les sources : un attaquant, beaucoup de comptes.", + "capBrute4": "Bloquez {{name}} sur le périmètre{{reset}}.", + "capBruteReset": " et réinitialisez {{account}}", + "capOut1": "{{who}} résout {{dest}}.", + "capOut2": "Il se connecte vers l'extérieur sur le port {{port}}{{through}}.", + "capOutThrough": " via {{name}}", + "capOut3": "La threat intelligence correspond à {{dest}} : {{kind}}.", + "capOut4": "La connexion a été interrompue et l'alerte levée pour que la machine soit vérifiée.", + "capOut5": "La connexion se répète : {{name}} est probablement infecté. Isolez-le et trouvez le processus.", + "capLat0": "{{name}}{{user}} contacte {{to}} à l'intérieur du réseau.", + "capLatUser": " ({{user}})", + "capLat1": "Il s'authentifie en tant que {{account}} avec {{how}}.", + "capLatHowHash": "un hachage de mot de passe volé", + "capLatHowKerb": "des tickets de service Kerberos qu'il peut casser hors ligne", + "capLatHowAsrep": "une réponse Kerberos pour un compte sans pré-authentification", + "capLatHowSmb": "l'ancien protocole SMBv1", + "capLatHowRdp": "des sessions distantes et des partages de fichiers", + "capLat2": "{{to}} accepte la session : l'attaquant se déplace maintenant entre les machines.", + "capLat3": "Désactivez {{account}} et vérifiez les deux machines.", + "capMal0": "Sur {{host}}{{user}} s'exécute {{proc}}.", + "capMalUser": ", {{user}}", + "capMal1": "{{p0}} démarre {{p1}} : inhabituel pour ce programme.", + "capMalChild": "un processus enfant", + "capMal2": "{{name}} s'exécute : {{detail}}.", + "capMalKnown": "une technique d'attaque connue", + "capMal3": "Arrêtez le processus ou isolez {{host}}.", + "capWeb0": "{{name}} sonde le serveur sur {{to}}.", + "capWeb1": "Il envoie des charges d'attaque : {{payloads}}…", + "capWeb2": "{{perimeter}} reconnaît les signatures d'attaque et abandonne les requêtes.", + "capWeb2b": "L'IPS reconnaît les signatures d'attaque et abandonne les requêtes.", + "capWeb3": "Certaines requêtes atteignent {{to}} ; le serveur répond par des erreurs et un 200 OK.", + "capWeb4": "Bloquez {{name}} et vérifiez les journaux du serveur.", + "capTrv0": "{{user}} se connecte depuis {{city}}, comme d'habitude.", + "capTrv1": "{{gap}} minutes plus tard, le même compte se connecte depuis {{city}}, {{country}}.", + "capTrvFar": "loin", + "capTrv2": "{{km}} km en {{gap}} minutes : personne ne voyage aussi vite. Le mot de passe est probablement volé.", + "capTrv3": "Révoquez les sessions et réinitialisez le mot de passe de {{user}}.", + "capScn0": "{{name}} commence à frapper sur {{to}}, un port après l'autre.", + "capScn1": "{{count}} ports sondés en quelques secondes : SSH, SMB, RDP, bases de données, consoles web…", + "capScn2": "Les ports {{open}} répondent ; le reste est fermé ou filtré.", + "capScn3": "Généralement la première étape d'une attaque : bloquez la source.", + "capCl0": "{{name}} se connecte à {{cloud}}{{from}}.", + "capClFrom": " depuis {{country}}", + "capClFromDef": "de l'extérieur de l'entreprise", + "capCl1": "Ils modifient {{what}}.", + "capCl3": "Confirmez que c'était prévu ou annulez-le.", + "capGen0": "{{src}} → {{tgt}}", + "capGen1": "{{what}}", + "capGenNew": "Nouvelle détection", + "capGen2": "Alerte levée : {{name}}.", + "capAlertRaised": "Alerte levée : {{name}}. ", + "capBlocked": "{{ip}} est maintenant bloqué sur {{on}} : le trafic s'arrête ici.", + "destUnknown": "destination inconnue", + "titleBrute": "Force brute depuis {{name}} contre {{to}}", + "titleOut": "{{name}} contacte {{to}}", + "titleLat": "{{name}} se déplace vers {{to}} en tant que {{account}}", + "titleMal": "{{name}} sur {{to}}", + "titleWeb": "Attaque web depuis {{name}} contre {{to}}", + "titleTrv": "{{name}} se connecte depuis deux continents", + "titleScn": "Scan de ports depuis {{name}}", + "titleCl": "{{what}} modifié dans {{to}}", + "titleAlert": "Alerte", + "dLsass": "vide la mémoire LSASS pour voler les mots de passe", + "dMiner": "mine de la cryptomonnaie avec le CPU du serveur", + "dRev": "ouvre une shell interactive vers l'attaquant", + "dKey": "exporte les mots de passe enregistrés du trousseau", + "dTask": "crée une tâche qui exécute une charge à chaque connexion", + "dAudit": "efface le journal de sécurité Windows", + "dFw": "supprime les règles du pare-feu de l'hôte", + "dShadow": "supprime les copies d'ombre avant le chiffrement", + "dDump": "outil d'extraction de credentials", + "dDl": "télécharge un outil dans un dossier modifiable", + "dPs": "exécute une commande encodée", + "capRan0": "Sur {{host}}{{user}}, un processus commence à toucher des centaines de fichiers à la fois.", + "capRanUser": ", {{user}}", + "capRan1": "Les fichiers sont renommés avec {{exts}} : les données sont chiffrées sur place.", + "capRan2": "Un mot de rançon est déposé : l’attaquant réclame un paiement pour restaurer les données.", + "capRan2b": "Les sauvegardes et les copies d’ombre sont supprimées : pas de retour facile.", + "capRan3": "Restaurer depuis les sauvegardes hors ligne et trouver le point d’entrée avant que le chiffrement ne se propage.", + "titleRan": "Rançlogiciel chiffrant {{to}}", + "capPer0": "Sur {{host}}{{user}}, quelque chose écrit dans les emplacements de démarrage du système.", + "capPer1": "Il dépose {{what}} : ces éléments s’exécutent automatiquement à chaque démarrage ou connexion.", + "capPer2": "Dernière pièce en place : {{what}}. L’emprise survit désormais aux redémarrages.", + "capPer3": "Supprimer les artefacts de persistance et chercher le vecteur d’infection initial.", + "titlePer": "Persistance installée sur {{to}} via {{what}}", + "dPersistCron": "exécute la charge selon une planification", + "dPersistSd": "démarre la charge à chaque démarrage", + "dPersistLaunch": "lance la charge à la connexion de l’utilisateur", + "dPersistKey": "permet à l’attaquant de revenir par SSH", + "dPersistRc": "exécute la charge dans chaque nouveau shell", + "dPersistPs": "exécute la charge dans chaque session PowerShell", + "dPersistPay": "le binaire de la charge lui-même", + "capExf0": "Sur {{host}}{{user}}, des données sensibles sont regroupées dans une archive.", + "capExf1": "Elles commencent à sortir via {{tool}}.", + "capExf2": "Les données arrivent à {{dest}} : elles sont maintenant hors de l’entreprise.", + "capExf3": "Bloquer le transfert, révoquer l’accès à {{dest}} et déterminer qui peut y accéder.", + "titleExf": "{{name}} exfiltre des données vers {{to}}", + "scDefenses": "Défenses", + "scDisabled": "✕ désactivé", + "scLogsCleared": "🗑 journaux effacés", + "dEvLog": "trace d’audit", + "dEvEnf": "application", + "capEv0": "Sur {{host}}, l’attaquant commence à toucher les éléments qui le surveillent.", + "capEv1": "{{what}} est désactivé : un de moins pour le voir.", + "capEv2": "Les journaux sont effacés : la trace de ses actions disparaît.", + "capEv2b": "Avec {{what}} désactivé, l’hôte est aveugle face à l’attaquant.", + "capEv3": "Restaurer les outils désactivés et préserver les journaux restants avant qu’ils ne disparaissent aussi.", + "titleEv": "Défenses désactivées sur {{to}}", + "scNormalUser": "utilisateur normal", + "scToken": "jeton", + "dEvUac": "UAC contournée", + "dEvToken": "jeton usurpé", + "dEvSuid": "binaire setuid abusé", + "dEvSudo": "cache de sudo abusée", + "dEvExploit": "noyau exploité", + "dEvDefault": "frontière de privilèges franchie", + "capPe0": "Sur {{host}}, la session tourne en tant qu’utilisateur normal.{{user}}", + "capPeUser": ", {{user}}", + "capPe1": "Il utilise {{method}} pour atteindre un niveau de privilège supérieur.", + "capPe2": "Les commandes tournent maintenant en tant que {{account}} : contrôle total de l’hôte.", + "capPe3": "Terminer la session élévée et auditer ce que {{account}} a pu toucher.", + "titlePe": "Élévation de privilèges sur {{to}} via {{method}}", + "alertRaised": "Alerte levée", + "userExec": "Utilisateur ouvre un fichier malveillant", + "softwareDeploy": "Logiciel poussé vers un hôte", + "phishing": "E-mail de phishing ouvert", + "processInjection": "Code injecté dans un processus", + "credDump": "Identifiants volés", + "dataDestruction": "Données détruites", + "toolDownload": "Outil téléchargé et exécuté", + "c2tunnel": "C2 à travers un tunnel", + "scExec": "Exécution", + "scPayload": "→ charge malveillante", + "capUe0": "Sur {{host}}{{user}}, l’utilisateur télécharge un fichier et l’ouvre.", + "capUeUser": ", {{user}}", + "capUe1": "Le fichier est ouvert : {{file}} est confié et exécuté.", + "capUe2": "{{app}} démarre un processus enfant qui exécute {{payload}}.", + "capUe3": "Mettre le fichier en quarantaine, bloquer son hash et vérifier les autres hôtes qui l’ont ouvert.", + "titleUe": "{{file}} ouvert sur {{to}}", + "scDeploy": "Déploiement", + "capSd0": "{{src}} pousse un logiciel vers {{to}} sur le réseau.", + "capSd1": "Il utilise {{tool}} : un canal qui installe sans interaction utilisateur.", + "capSd2": "Le paquet est installé sur {{to}} et démarre avec lui.", + "capSd3": "Arrêter le déploiement, retirer le composant installé et auditer ce qu’il a fait.", + "titleSd": "Logiciel déployé de {{src}} vers {{to}}", + "scAttachment": "pièce jointe ouverte", + "capPh0": "{{name}} envoie un e-mail de phishing dans l’entreprise.", + "capPh1": "Le message arrive dans la boîte de {{user}} et est ouvert.", + "capPh2": "La pièce jointe s’exécute : {{file}} tourne sur la machine.", + "capPh3": "Mettre l’e-mail en quarantaine, bloquer l’expéditeur et retirer {{file}} de la machine de {{user}}.", + "titlePh": "E-mail de phishing ouvert par {{user}} (de {{from}})", + "scInject": "Injection", + "scInside": "— code dans un processus de confiance", + "capPi0": "Sur {{host}}, le chargeur de l’attaquant démarre : {{injector}}.", + "capPi1": "Il injecte du code dans un processus de confiance : {{victim}}.", + "capPi2": "{{victim}} exécute maintenant le code de l’attaquant avec ses propres privilèges.", + "capPi3": "Tuer le code injecté, retirer le chargeur et chercher d’autres victimes.", + "titlePi": "{{injector}} injecte du code dans {{victim}}", + "scCred": "Magasin de credentials", + "scSecrets": "{{n}} secrets", + "scSecret": "secret", + "scStolen": "✕ identifiants volés", + "capCd0": "Sur {{host}}, un outil commence à lire le magasin de credentials.", + "capCd1": "Il ouvre {{store}} et extrait le matériau stocké.", + "capCd2": "{{n}} identifiants sont capturés : comptes, clés et haches.", + "capCd3": "Faire tourner tous les identifiants du magasin et chasser l’outil de vol.", + "titleCd": "{{store}} volé sur {{host}}", + "scData": "Données", + "scDataItem": "jeu-{{i}}", + "scGone": "parties", + "scNoRecovery": "données détruites", + "capDd0": "Sur {{host}}, quelque chose efface des données au lieu de les chiffrer.", + "capDd1": "{{n}} jeux de données sont détruits, l’un après l’autre.", + "capDd2": "Les données sont supprimées à nu : pas de note, pas de rançon, pas de retour.", + "capDd3": "Arrêter le processus d’origine et restaurer ce qui reste depuis les sauvegardes hors ligne.", + "titleDd": "Données détruites sur {{host}}", + "scDownload": "octets", + "scExecuted": "exécuté", + "capTd0": "{{src}} sert un outil à {{to}}.", + "capTd1": "Il est téléchargé dans un dossier accessible en écriture : {{folder}}.", + "capTd2": "Le fichier s’exécute : {{tool}} tourne maintenant.", + "capTd3": "Supprimer l’outil, bloquer son hash et vérifier quels hôtes l’ont exécuté.", + "titleTd": "{{src}} dépose un outil sur {{to}}", + "scTunnel": "caché dans le trafic {{proto}}", + "scTunneled": "Octets acheminés", + "capCt0": "{{src}} communique avec {{to}} via un protocole qui a l’air normal.", + "capCt1": "La charge est dissimulée dans le trafic {{proto}}.", + "capCt2": "Commandes et données traversent la frontière invisibles, portées par {{proto}}.", + "capCt3": "Couper le tunnel, bloquer l’extrémité et inspecter ce qui est passé.", + "titleCt": "{{src}} tunnelise du C2 via {{proto}} vers {{to}}", + "netPerimeter": "Périmètre", + "scDc": "Contrôleur de domaine", + "scObject": "Objet modifié", + "scChangedBy": "modifié par", + "scHighRisk": "changement à haut risque", + "scTktAsk": "demande de billet", + "scTktUses": "réutilisé sur {{n}} services", + "scTerminal": "Terminal", + "scRunning": "…en cours", + "scAmsiOff": "⚠ AMSI désactivé", + "scConn": "TCP {{port}}", + "scShellOn": "$ shell inversé", + "scHypervisor": "Hyperviseur", + "scGuestVm": "machine virtuelle invitée", + "scConfined": "confiné à l’invité", + "scEscaped": "évasé vers le hôte", + "scBoundary": "frontière de l’invité franchie", + "scFeedAsk": "feed ? {{ioc}}", + "scFeedBad": "MAUVAIS", + "scFeedHit": "Intel menaces : {{kind}}", + "scDroppedAtFw": "✕ abandonné à {{fw}}", + "scTrafficStops": "le trafic s’arrête ici", + "scSigHits": "Hits signature", + "capIoc0": "{{src}} se connecte à {{ioc}}.", + "capIoc1": "L’intelligence menace le flag : {{kind}}.", + "capIoc2": "{{ioc}} est sur la liste de blocage : la connexion est coupée.", + "capIoc3": "Bloquer {{ioc}} au bord et vérifier ce qui est déjà sorti du réseau.", + "titleIoc": "{{src}} atteint un {{ioc}} connu", + "capPd0": "{{name}} envoie une {{sig}} au périmètre.", + "capPd1": "{{fw}} matche la signature et déclenche.", + "capPd2": "Le trafic est abandonné : le périmètre a tenu.", + "capPd3": "Le trafic traverse {{fw}} : l’alerte est informative.", + "capPd4": "Vérifier la signature et bloquer la source si elle persiste.", + "titlePd": "{{sig}} bloqué à {{fw}}", + "capAc0": "{{who}} modifie {{what}} sur {{host}}.", + "capAc1": "Le {{what}} est modifié.", + "capAc2": "{{before}} → {{after}}.", + "capAc3": "Confirmer que c’était planifié, ou annuler le changement de {{who}}.", + "titleAc": "{{what}} modifié sur {{host}}", + "capKb0": "{{src}} demande des billets Kerberos à {{dc}}.", + "capKb1": "Le {{ticket}} obtenu est {{kind}}.", + "capKb2": "Il est réutilisé sur {{services}} : le DC l’accepte à chaque fois.", + "capKb3": "Réinitialiser le mot de passe krbtgt et auditer les billets émis ces 48 h.", + "titleKb": "{{src}} forge des billets Kerberos via {{dc}}", + "capPs0": "Sur {{host}}, un script démarre avec du contenu encodé.", + "capPs1": "Il décode une commande et désactive le sensor antimalware (AMSI).", + "capPs2": "La commande décodée s’exécute : c’est une charge, pas un script.", + "capPs2a": "AMSI est d’abord désactivé, puis la commande encodée tourne sans être vue.", + "capPs3": "Bloquer le hash, chercher d’autres machines avec le même script.", + "titlePs2": "Script encodé en cours d’exécution sur {{host}}", + "capRs0": "Sur {{host}}, un processus ouvre un socket vers l’extérieur.", + "capRs1": "Il se reconnecte à {{name}} sur le port {{port}} : une shell inversée.", + "capRs2": "Un prompt apparaît : l’attaquant peut maintenant taper des commandes sur le hôte.", + "capRs3": "Tuer la connexion, isoler {{host}} et vérifier ce qui a été tapé.", + "titleRs": "Shell inversée ouverte sur {{host}}", + "capVm0": "La VM invitée {{guest}} exécute un processus avec un accès hôte.", + "capVm1": "Il tente de franchir la frontière de l’hyperviseur.", + "capVm2": "Le processus tourne sur le hôte {{host}} : l’invité n’est plus une cage.", + "capVm3": "Panic l’hyperviseur, snapshoter l’invité et le reconstruire.", + "titleVm": "Invité {{guest}} qui s’évade vers {{host}}", + "listNew": "Nouvelle", + "newAlertsCount_one": "{{count}} nouvelle alerte", + "newAlertsCount_other": "{{count}} nouvelles alertes", + "statTotal": "Total", + "timPage": "Page {{p}}/{{n}}", + "timPagePrev": "Page précédente", + "timPageNext": "Page suivante", + "newAlerts": "Nouvelles alertes" }, - "replayTip": "Rejouer toutes les alertes de cette fenêtre dans l'ordre", - "liveTip": "Suivre les nouvelles alertes à mesure qu'elles arrivent", - "playAgain": "Rejouer cette alerte", - "alertAt": "{{name}} à {{time}}", - "netInternet": "Internet", - "netInternal": "Réseau interne", - "scUser": "utilisateur : {{account}}", - "scWrongPassword": "✕ mauvais mot de passe", - "scSignedIn": "✓ connecté", - "scSignedInAs": "connecté en tant que {{account}}", - "scFailedSignins": "Échecs de connexion", - "scBlocked": "🛡 {{name}} bloqué", - "scSessionAs": "session en tant que {{account}}", - "scHost": "Hôte · {{name}}", - "scFiles": "Documents", - "scBackups": "Copies d’ombre", - "scRansomNote": "🔒 NOTE DE RANÇON", - "scShadows": "✕ copies d’ombre supprimées", - "scPersist": "Persistance", - "scReboot": "survit aux redémarrages — porte dérobée installée", - "scCloud": "Stockage externe", - "scChunk": "données", - "scExfilBytes": "Données exfiltrées", - "scProcessTree": "Arbre de processus", - "scDns": "DNS ? {{host}}", - "scThreatIntel": "Intel menaces : Alarmant (-3)", - "scConnDropped": "✕ connexion interrompue", - "scPortsProbed": "Ports sondés", - "scSignIn": "✓ connexion", - "scKmInMin": "{{km}} km en {{min}} min", - "scAbroad": "à l'étranger", - "scDropped": "{{status}} bloqué", - "scBeacon": "balise", - "capBrute0": "{{name}}{{sub}} commence à deviner les mots de passe contre {{where}}.", - "capBruteVpn": "le VPN sur {{name}}", - "capBrute1": "{{attempts}} échecs de connexion en {{minutes}} minutes, en faisant tourner {{count}} noms de compte.", - "capBrute2": "Une connexion en tant que {{account}} réussit juste après les échecs : le mot de passe a été deviné.", - "capBrute3": "Corrélation des échecs entre les sources : un attaquant, beaucoup de comptes.", - "capBrute4": "Bloquez {{name}} sur le périmètre{{reset}}.", - "capBruteReset": " et réinitialisez {{account}}", - "capOut1": "{{who}} résout {{dest}}.", - "capOut2": "Il se connecte vers l'extérieur sur le port {{port}}{{through}}.", - "capOutThrough": " via {{name}}", - "capOut3": "La threat intelligence correspond à {{dest}} : {{kind}}.", - "capOut4": "La connexion a été interrompue et l'alerte levée pour que la machine soit vérifiée.", - "capOut5": "La connexion se répète : {{name}} est probablement infecté. Isolez-le et trouvez le processus.", - "capLat0": "{{name}}{{user}} contacte {{to}} à l'intérieur du réseau.", - "capLatUser": " ({{user}})", - "capLat1": "Il s'authentifie en tant que {{account}} avec {{how}}.", - "capLatHowHash": "un hachage de mot de passe volé", - "capLatHowKerb": "des tickets de service Kerberos qu'il peut casser hors ligne", - "capLatHowAsrep": "une réponse Kerberos pour un compte sans pré-authentification", - "capLatHowSmb": "l'ancien protocole SMBv1", - "capLatHowRdp": "des sessions distantes et des partages de fichiers", - "capLat2": "{{to}} accepte la session : l'attaquant se déplace maintenant entre les machines.", - "capLat3": "Désactivez {{account}} et vérifiez les deux machines.", - "capMal0": "Sur {{host}}{{user}} s'exécute {{proc}}.", - "capMalUser": ", {{user}}", - "capMal1": "{{p0}} démarre {{p1}} : inhabituel pour ce programme.", - "capMalChild": "un processus enfant", - "capMal2": "{{name}} s'exécute : {{detail}}.", - "capMalKnown": "une technique d'attaque connue", - "capMal3": "Arrêtez le processus ou isolez {{host}}.", - "capWeb0": "{{name}} sonde le serveur sur {{to}}.", - "capWeb1": "Il envoie des charges d'attaque : {{payloads}}…", - "capWeb2": "{{perimeter}} reconnaît les signatures d'attaque et abandonne les requêtes.", - "capWeb2b": "L'IPS reconnaît les signatures d'attaque et abandonne les requêtes.", - "capWeb3": "Certaines requêtes atteignent {{to}} ; le serveur répond par des erreurs et un 200 OK.", - "capWeb4": "Bloquez {{name}} et vérifiez les journaux du serveur.", - "capTrv0": "{{user}} se connecte depuis {{city}}, comme d'habitude.", - "capTrv1": "{{gap}} minutes plus tard, le même compte se connecte depuis {{city}}, {{country}}.", - "capTrvFar": "loin", - "capTrv2": "{{km}} km en {{gap}} minutes : personne ne voyage aussi vite. Le mot de passe est probablement volé.", - "capTrv3": "Révoquez les sessions et réinitialisez le mot de passe de {{user}}.", - "capScn0": "{{name}} commence à frapper sur {{to}}, un port après l'autre.", - "capScn1": "{{count}} ports sondés en quelques secondes : SSH, SMB, RDP, bases de données, consoles web…", - "capScn2": "Les ports {{open}} répondent ; le reste est fermé ou filtré.", - "capScn3": "Généralement la première étape d'une attaque : bloquez la source.", - "capCl0": "{{name}} se connecte à {{cloud}}{{from}}.", - "capClFrom": " depuis {{country}}", - "capClFromDef": "de l'extérieur de l'entreprise", - "capCl1": "Ils modifient {{what}}.", - "capCl3": "Confirmez que c'était prévu ou annulez-le.", - "capGen0": "{{src}} → {{tgt}}", - "capGen1": "{{what}}", - "capGenNew": "Nouvelle détection", - "capGen2": "Alerte levée : {{name}}.", - "capAlertRaised": "Alerte levée : {{name}}. ", - "capBlocked": "{{ip}} est maintenant bloqué sur {{on}} : le trafic s'arrête ici.", - "destUnknown": "destination inconnue", - "titleBrute": "Force brute depuis {{name}} contre {{to}}", - "titleOut": "{{name}} contacte {{to}}", - "titleLat": "{{name}} se déplace vers {{to}} en tant que {{account}}", - "titleMal": "{{name}} sur {{to}}", - "titleWeb": "Attaque web depuis {{name}} contre {{to}}", - "titleTrv": "{{name}} se connecte depuis deux continents", - "titleScn": "Scan de ports depuis {{name}}", - "titleCl": "{{what}} modifié dans {{to}}", - "titleAlert": "Alerte", - "dLsass": "vide la mémoire LSASS pour voler les mots de passe", - "dMiner": "mine de la cryptomonnaie avec le CPU du serveur", - "dRev": "ouvre une shell interactive vers l'attaquant", - "dKey": "exporte les mots de passe enregistrés du trousseau", - "dTask": "crée une tâche qui exécute une charge à chaque connexion", - "dAudit": "efface le journal de sécurité Windows", - "dFw": "supprime les règles du pare-feu de l'hôte", - "dShadow": "supprime les copies d'ombre avant le chiffrement", - "dDump": "outil d'extraction de credentials", - "dDl": "télécharge un outil dans un dossier modifiable", - "dPs": "exécute une commande encodée", - "capRan0": "Sur {{host}}{{user}}, un processus commence à toucher des centaines de fichiers à la fois.", - "capRanUser": ", {{user}}", - "capRan1": "Les fichiers sont renommés avec {{exts}} : les données sont chiffrées sur place.", - "capRan2": "Un mot de rançon est déposé : l’attaquant réclame un paiement pour restaurer les données.", - "capRan2b": "Les sauvegardes et les copies d’ombre sont supprimées : pas de retour facile.", - "capRan3": "Restaurer depuis les sauvegardes hors ligne et trouver le point d’entrée avant que le chiffrement ne se propage.", - "titleRan": "Rançlogiciel chiffrant {{to}}", - "capPer0": "Sur {{host}}{{user}}, quelque chose écrit dans les emplacements de démarrage du système.", - "capPer1": "Il dépose {{what}} : ces éléments s’exécutent automatiquement à chaque démarrage ou connexion.", - "capPer2": "Dernière pièce en place : {{what}}. L’emprise survit désormais aux redémarrages.", - "capPer3": "Supprimer les artefacts de persistance et chercher le vecteur d’infection initial.", - "titlePer": "Persistance installée sur {{to}} via {{what}}", - "dPersistCron": "exécute la charge selon une planification", - "dPersistSd": "démarre la charge à chaque démarrage", - "dPersistLaunch": "lance la charge à la connexion de l’utilisateur", - "dPersistKey": "permet à l’attaquant de revenir par SSH", - "dPersistRc": "exécute la charge dans chaque nouveau shell", - "dPersistPs": "exécute la charge dans chaque session PowerShell", - "dPersistPay": "le binaire de la charge lui-même", - "capExf0": "Sur {{host}}{{user}}, des données sensibles sont regroupées dans une archive.", - "capExf1": "Elles commencent à sortir via {{tool}}.", - "capExf2": "Les données arrivent à {{dest}} : elles sont maintenant hors de l’entreprise.", - "capExf3": "Bloquer le transfert, révoquer l’accès à {{dest}} et déterminer qui peut y accéder.", - "titleExf": "{{name}} exfiltre des données vers {{to}}", - "scDefenses": "Défenses", - "scDisabled": "✕ désactivé", - "scLogsCleared": "🗑 journaux effacés", - "dEvLog": "trace d’audit", - "dEvEnf": "application", - "capEv0": "Sur {{host}}, l’attaquant commence à toucher les éléments qui le surveillent.", - "capEv1": "{{what}} est désactivé : un de moins pour le voir.", - "capEv2": "Les journaux sont effacés : la trace de ses actions disparaît.", - "capEv2b": "Avec {{what}} désactivé, l’hôte est aveugle face à l’attaquant.", - "capEv3": "Restaurer les outils désactivés et préserver les journaux restants avant qu’ils ne disparaissent aussi.", - "titleEv": "Défenses désactivées sur {{to}}", - "scNormalUser": "utilisateur normal", - "scToken": "jeton", - "dEvUac": "UAC contournée", - "dEvToken": "jeton usurpé", - "dEvSuid": "binaire setuid abusé", - "dEvSudo": "cache de sudo abusée", - "dEvExploit": "noyau exploité", - "dEvDefault": "frontière de privilèges franchie", - "capPe0": "Sur {{host}}, la session tourne en tant qu’utilisateur normal.{{user}}", - "capPeUser": ", {{user}}", - "capPe1": "Il utilise {{method}} pour atteindre un niveau de privilège supérieur.", - "capPe2": "Les commandes tournent maintenant en tant que {{account}} : contrôle total de l’hôte.", - "capPe3": "Terminer la session élévée et auditer ce que {{account}} a pu toucher.", - "titlePe": "Élévation de privilèges sur {{to}} via {{method}}", - "alertRaised": "Alerte levée", - "userExec": "Utilisateur ouvre un fichier malveillant", - "softwareDeploy": "Logiciel poussé vers un hôte", - "phishing": "E-mail de phishing ouvert", - "processInjection": "Code injecté dans un processus", - "credDump": "Identifiants volés", - "dataDestruction": "Données détruites", - "toolDownload": "Outil téléchargé et exécuté", - "c2tunnel": "C2 à travers un tunnel", "scExec": "Exécution", "scPayload": "→ charge malveillante", "capUe0": "Sur {{host}}{{user}}, l’utilisateur télécharge un fichier et l’ouvre.", @@ -6512,133 +6664,5 @@ "capCt1": "La charge est dissimulée dans le trafic {{proto}}.", "capCt2": "Commandes et données traversent la frontière invisibles, portées par {{proto}}.", "capCt3": "Couper le tunnel, bloquer l’extrémité et inspecter ce qui est passé.", - "titleCt": "{{src}} tunnelise du C2 via {{proto}} vers {{to}}", - "netPerimeter": "Périmètre", - "scDc": "Contrôleur de domaine", - "scObject": "Objet modifié", - "scChangedBy": "modifié par", - "scHighRisk": "changement à haut risque", - "scTktAsk": "demande de billet", - "scTktUses": "réutilisé sur {{n}} services", - "scTerminal": "Terminal", - "scRunning": "…en cours", - "scAmsiOff": "⚠ AMSI désactivé", - "scConn": "TCP {{port}}", - "scShellOn": "$ shell inversé", - "scHypervisor": "Hyperviseur", - "scGuestVm": "machine virtuelle invitée", - "scConfined": "confiné à l’invité", - "scEscaped": "évasé vers le hôte", - "scBoundary": "frontière de l’invité franchie", - "scFeedAsk": "feed ? {{ioc}}", - "scFeedBad": "MAUVAIS", - "scFeedHit": "Intel menaces : {{kind}}", - "scDroppedAtFw": "✕ abandonné à {{fw}}", - "scTrafficStops": "le trafic s’arrête ici", - "scSigHits": "Hits signature", - "capIoc0": "{{src}} se connecte à {{ioc}}.", - "capIoc1": "L’intelligence menace le flag : {{kind}}.", - "capIoc2": "{{ioc}} est sur la liste de blocage : la connexion est coupée.", - "capIoc3": "Bloquer {{ioc}} au bord et vérifier ce qui est déjà sorti du réseau.", - "titleIoc": "{{src}} atteint un {{ioc}} connu", - "capPd0": "{{name}} envoie une {{sig}} au périmètre.", - "capPd1": "{{fw}} matche la signature et déclenche.", - "capPd2": "Le trafic est abandonné : le périmètre a tenu.", - "capPd3": "Le trafic traverse {{fw}} : l’alerte est informative.", - "capPd4": "Vérifier la signature et bloquer la source si elle persiste.", - "titlePd": "{{sig}} bloqué à {{fw}}", - "capAc0": "{{who}} modifie {{what}} sur {{host}}.", - "capAc1": "Le {{what}} est modifié.", - "capAc2": "{{before}} → {{after}}.", - "capAc3": "Confirmer que c’était planifié, ou annuler le changement de {{who}}.", - "titleAc": "{{what}} modifié sur {{host}}", - "capKb0": "{{src}} demande des billets Kerberos à {{dc}}.", - "capKb1": "Le {{ticket}} obtenu est {{kind}}.", - "capKb2": "Il est réutilisé sur {{services}} : le DC l’accepte à chaque fois.", - "capKb3": "Réinitialiser le mot de passe krbtgt et auditer les billets émis ces 48 h.", - "titleKb": "{{src}} forge des billets Kerberos via {{dc}}", - "capPs0": "Sur {{host}}, un script démarre avec du contenu encodé.", - "capPs1": "Il décode une commande et désactive le sensor antimalware (AMSI).", - "capPs2": "La commande décodée s’exécute : c’est une charge, pas un script.", - "capPs2a": "AMSI est d’abord désactivé, puis la commande encodée tourne sans être vue.", - "capPs3": "Bloquer le hash, chercher d’autres machines avec le même script.", - "titlePs2": "Script encodé en cours d’exécution sur {{host}}", - "capRs0": "Sur {{host}}, un processus ouvre un socket vers l’extérieur.", - "capRs1": "Il se reconnecte à {{name}} sur le port {{port}} : une shell inversée.", - "capRs2": "Un prompt apparaît : l’attaquant peut maintenant taper des commandes sur le hôte.", - "capRs3": "Tuer la connexion, isoler {{host}} et vérifier ce qui a été tapé.", - "titleRs": "Shell inversée ouverte sur {{host}}", - "capVm0": "La VM invitée {{guest}} exécute un processus avec un accès hôte.", - "capVm1": "Il tente de franchir la frontière de l’hyperviseur.", - "capVm2": "Le processus tourne sur le hôte {{host}} : l’invité n’est plus une cage.", - "capVm3": "Panic l’hyperviseur, snapshoter l’invité et le reconstruire.", - "titleVm": "Invité {{guest}} qui s’évade vers {{host}}", - "listNew": "Nouvelle", - "newAlertsCount_one": "{{count}} nouvelle alerte", - "newAlertsCount_other": "{{count}} nouvelles alertes", - "statTotal": "Total", - "timPage": "Page {{p}}/{{n}}", - "timPagePrev": "Page précédente", - "timPageNext": "Page suivante", - "newAlerts": "Nouvelles alertes" - }, - "scExec": "Exécution", - "scPayload": "→ charge malveillante", - "capUe0": "Sur {{host}}{{user}}, l’utilisateur télécharge un fichier et l’ouvre.", - "capUeUser": ", {{user}}", - "capUe1": "Le fichier est ouvert : {{file}} est confié et exécuté.", - "capUe2": "{{app}} démarre un processus enfant qui exécute {{payload}}.", - "capUe3": "Mettre le fichier en quarantaine, bloquer son hash et vérifier les autres hôtes qui l’ont ouvert.", - "titleUe": "{{file}} ouvert sur {{to}}", - "scDeploy": "Déploiement", - "capSd0": "{{src}} pousse un logiciel vers {{to}} sur le réseau.", - "capSd1": "Il utilise {{tool}} : un canal qui installe sans interaction utilisateur.", - "capSd2": "Le paquet est installé sur {{to}} et démarre avec lui.", - "capSd3": "Arrêter le déploiement, retirer le composant installé et auditer ce qu’il a fait.", - "titleSd": "Logiciel déployé de {{src}} vers {{to}}", - "scAttachment": "pièce jointe ouverte", - "capPh0": "{{name}} envoie un e-mail de phishing dans l’entreprise.", - "capPh1": "Le message arrive dans la boîte de {{user}} et est ouvert.", - "capPh2": "La pièce jointe s’exécute : {{file}} tourne sur la machine.", - "capPh3": "Mettre l’e-mail en quarantaine, bloquer l’expéditeur et retirer {{file}} de la machine de {{user}}.", - "titlePh": "E-mail de phishing ouvert par {{user}} (de {{from}})", - "scInject": "Injection", - "scInside": "— code dans un processus de confiance", - "capPi0": "Sur {{host}}, le chargeur de l’attaquant démarre : {{injector}}.", - "capPi1": "Il injecte du code dans un processus de confiance : {{victim}}.", - "capPi2": "{{victim}} exécute maintenant le code de l’attaquant avec ses propres privilèges.", - "capPi3": "Tuer le code injecté, retirer le chargeur et chercher d’autres victimes.", - "titlePi": "{{injector}} injecte du code dans {{victim}}", - "scCred": "Magasin de credentials", - "scSecrets": "{{n}} secrets", - "scSecret": "secret", - "scStolen": "✕ identifiants volés", - "capCd0": "Sur {{host}}, un outil commence à lire le magasin de credentials.", - "capCd1": "Il ouvre {{store}} et extrait le matériau stocké.", - "capCd2": "{{n}} identifiants sont capturés : comptes, clés et haches.", - "capCd3": "Faire tourner tous les identifiants du magasin et chasser l’outil de vol.", - "titleCd": "{{store}} volé sur {{host}}", - "scData": "Données", - "scDataItem": "jeu-{{i}}", - "scGone": "parties", - "scNoRecovery": "données détruites", - "capDd0": "Sur {{host}}, quelque chose efface des données au lieu de les chiffrer.", - "capDd1": "{{n}} jeux de données sont détruits, l’un après l’autre.", - "capDd2": "Les données sont supprimées à nu : pas de note, pas de rançon, pas de retour.", - "capDd3": "Arrêter le processus d’origine et restaurer ce qui reste depuis les sauvegardes hors ligne.", - "titleDd": "Données détruites sur {{host}}", - "scDownload": "octets", - "scExecuted": "exécuté", - "capTd0": "{{src}} sert un outil à {{to}}.", - "capTd1": "Il est téléchargé dans un dossier accessible en écriture : {{folder}}.", - "capTd2": "Le fichier s’exécute : {{tool}} tourne maintenant.", - "capTd3": "Supprimer l’outil, bloquer son hash et vérifier quels hôtes l’ont exécuté.", - "titleTd": "{{src}} dépose un outil sur {{to}}", - "scTunnel": "caché dans le trafic {{proto}}", - "scTunneled": "Octets acheminés", - "capCt0": "{{src}} communique avec {{to}} via un protocole qui a l’air normal.", - "capCt1": "La charge est dissimulée dans le trafic {{proto}}.", - "capCt2": "Commandes et données traversent la frontière invisibles, portées par {{proto}}.", - "capCt3": "Couper le tunnel, bloquer l’extrémité et inspecter ce qui est passé.", - "titleCt": "{{src}} tunnelise du C2 via {{proto}} vers {{to}}" + "titleCt": "{{src}} tunnelise du C2 via {{proto}} vers {{to}}" } diff --git a/frontend/src/shared/i18n/locales/it.json b/frontend/src/shared/i18n/locales/it.json index 0802d93c0..defb9aa38 100644 --- a/frontend/src/shared/i18n/locales/it.json +++ b/frontend/src/shared/i18n/locales/it.json @@ -1,6459 +1,6611 @@ { - "onboarding": { - "adminEmail": { - "title": "Imposta l'email dell'amministratore", - "subtitle": "Richiesto prima di continuare", - "description": "Il tuo account amministratore usa ancora l'email predefinita. Imposta un indirizzo reale — serve per il recupero della password, le notifiche e le email di avviso.", - "emailLabel": "Indirizzo email", - "save": "Salva e continua", - "saving": "Salvataggio…", - "success": "Email dell'amministratore impostata. Ora configura il tuo server di posta.", - "error": "Impossibile salvare la tua email. Riprova." - } - }, - "common": { - "appName": "UTMStack", - "language": "Lingua", - "actions": { - "save": "Salva", - "cancel": "Annulla", - "retry": "Riprova", - "refresh": "Aggiorna", - "delete": "Elimina", - "remove": "Rimuovi", - "close": "Chiudi", - "next": "Avanti", - "back": "Indietro" - }, - "confirm": { - "delete": "Elimina", - "working": "Operazione in corso…" - }, - "dateRange": { - "pick": "Scegli un intervallo", - "clear": "Cancella", - "done": "Fine", - "apply": "Applica" - }, - "loadingMore": "Caricamento in corso…", - "allLoaded": "{{count}} caricati", - "startFrom": { - "scratch": "Da zero", - "scratchHint": "Una definizione vuota che compili tu.", - "copy": "Da una esistente", - "copyHint": "Viene copiato tutto tranne identificatore e nome.", - "pickTitle": "Scegli cosa copiare", - "back": "Indietro", - "count": "{{n}} disponibili", - "search": "Cerca per nome", - "none": "Nessun risultato per questa ricerca" + "onboarding": { + "adminEmail": { + "title": "Imposta l'email dell'amministratore", + "subtitle": "Richiesto prima di continuare", + "description": "Il tuo account amministratore usa ancora l'email predefinita. Imposta un indirizzo reale — serve per il recupero della password, le notifiche e le email di avviso.", + "emailLabel": "Indirizzo email", + "save": "Salva e continua", + "saving": "Salvataggio…", + "success": "Email dell'amministratore impostata. Ora configura il tuo server di posta.", + "error": "Impossibile salvare la tua email. Riprova." + } }, - "cancel": "Annulla" - }, - "auth": { - "login": { - "title": "Bentornato", - "subtitle": "Accedi per continuare su {{brand}}", - "loginLabel": "E-mail", - "passwordLabel": "Password", - "forgot": "Dimenticata?", - "submit": "Accedi", - "terms": "Accedendo, accetti i termini di servizio di {{brand}}.", - "orContinueWith": "oppure continua con", - "continueWith": "Continua con {{name}}", - "signingInTo": "Accesso a {{name}}", - "useAnother": "Usane un altro" + "common": { + "appName": "UTMStack", + "language": "Lingua", + "actions": { + "save": "Salva", + "cancel": "Annulla", + "retry": "Riprova", + "refresh": "Aggiorna", + "delete": "Elimina", + "remove": "Rimuovi", + "close": "Chiudi", + "next": "Avanti", + "back": "Indietro" + }, + "confirm": { + "delete": "Elimina", + "working": "Operazione in corso…" + }, + "dateRange": { + "pick": "Scegli un intervallo", + "clear": "Cancella", + "done": "Fine", + "apply": "Applica" + }, + "loadingMore": "Caricamento in corso…", + "allLoaded": "{{count}} caricati", + "startFrom": { + "scratch": "Da zero", + "scratchHint": "Una definizione vuota che compili tu.", + "copy": "Da una esistente", + "copyHint": "Viene copiato tutto tranne identificatore e nome.", + "pickTitle": "Scegli cosa copiare", + "back": "Indietro", + "count": "{{n}} disponibili", + "search": "Cerca per nome", + "none": "Nessun risultato per questa ricerca" + }, + "cancel": "Annulla" + }, + "auth": { + "login": { + "title": "Bentornato", + "subtitle": "Accedi per continuare su {{brand}}", + "loginLabel": "E-mail", + "passwordLabel": "Password", + "forgot": "Dimenticata?", + "submit": "Accedi", + "terms": "Accedendo, accetti i termini di servizio di {{brand}}.", + "orContinueWith": "oppure continua con", + "continueWith": "Continua con {{name}}", + "signingInTo": "Accesso a {{name}}", + "useAnother": "Usane un altro" + }, + "tfa": { + "title": "Verifica in due passaggi", + "subtitleTotp": "Inserisci il codice a 6 cifre della tua app di autenticazione.", + "subtitleEmail": "Inserisci il codice a 6 cifre che ti abbiamo inviato via email.", + "codeLabel": "Codice di verifica", + "submit": "Verifica", + "back": "Torna all'accesso" + }, + "forgot": { + "title": "Reimposta la password", + "subtitle": "Ti invieremo un link via email per impostare una nuova password.", + "emailLabel": "Email", + "submit": "Invia link", + "sent": "Se quell'email è registrata, il link di reimpostazione è in arrivo." + }, + "errors": { + "tooManyAttempts": "Troppi tentativi. Riprova tra qualche minuto.", + "deactivated": "Questo account è disattivato.", + "invalidCredentials": "Credenziali non valide.", + "codeExpired": "Questo codice è scaduto. Accedi di nuovo.", + "loginFailed": "Accesso non riuscito. Riprova.", + "invalidCode": "Codice non valido o scaduto.", + "verifyFailed": "Verifica non riuscita. Riprova.", + "resetFailed": "Impossibile inviare l'email di reimpostazione. Riprova.", + "ssoFailed": "L'accesso unico non è stato completato. Riprova o usa la tua password." + } }, - "tfa": { - "title": "Verifica in due passaggi", - "subtitleTotp": "Inserisci il codice a 6 cifre della tua app di autenticazione.", - "subtitleEmail": "Inserisci il codice a 6 cifre che ti abbiamo inviato via email.", - "codeLabel": "Codice di verifica", - "submit": "Verifica", - "back": "Torna all'accesso" + "profile": { + "hero": { + "administrator": "Amministratore", + "changeAvatar": "Cambia avatar", + "removeAvatar": "Rimuovi avatar" + }, + "personal": { + "title": "Informazioni personali", + "description": "Aggiorna il tuo nome e i tuoi contatti.", + "firstName": "Nome", + "lastName": "Cognome", + "email": "Email", + "language": "Lingua", + "languageHint": "Usata per l'interfaccia del pannello.", + "systemDefault": "Predefinito del sistema", + "username": "Nome utente", + "usernameHint": "Il nome utente non può essere modificato.", + "reset": "Reimposta", + "save": "Salva modifiche", + "saving": "Salvataggio…", + "name": "Nome" + }, + "password": { + "title": "Password", + "description": "Usa una password forte che non riutilizzi da nessun'altra parte.", + "current": "Password attuale", + "new": "Nuova password", + "newHint": "Almeno 8 caratteri.", + "confirm": "Conferma nuova password", + "update": "Aggiorna password", + "updating": "Aggiornamento…" + }, + "sessions": { + "title": "Sessioni attive", + "description": "Dispositivi attualmente connessi al tuo account.", + "loading": "Caricamento sessioni…", + "empty": "Nessuna sessione attiva.", + "thisDevice": "Questo dispositivo", + "unknownIp": "IP sconosciuto", + "unknownDevice": "Dispositivo sconosciuto", + "deviceLabel": "{{browser}} su {{os}}", + "signedIn": "Accesso {{time}}", + "revoke": "Revoca", + "revoking": "Revoca in corso…", + "signOutOthers": "Disconnetti tutte le altre sessioni", + "signingOut": "Disconnessione…" + }, + "tfa": { + "title": "Autenticazione a due fattori", + "description": "Aggiungi un ulteriore livello di sicurezza al tuo account.", + "loading": "Caricamento…", + "methodTotp": "App di autenticazione", + "methodEmail": "Codice via email", + "onTitle": "L'autenticazione a due fattori è attiva", + "method": "Metodo: {{method}}", + "configured": "Configurato", + "disable": "Disattiva", + "disableTitle": "Disattiva l'autenticazione a due fattori", + "disableDescription": "Inserisci la password attuale per confermare. Il tuo account si baserà solo sulla password in seguito.", + "currentPasswordPlaceholder": "Password attuale", + "disableConfirm": "Disattiva 2FA", + "disabling": "Disattivazione…", + "offTitle": "L'autenticazione a due fattori è disattivata", + "status": "Stato:", + "notConfigured": "Non configurato", + "enable": "Attiva", + "chooseMethod": "Scegli un metodo", + "totpDesc": "Usa Google Authenticator, 1Password, ecc. Consigliato.", + "emailDesc": "Ricevi un codice a 6 cifre via email all'accesso.", + "noEmailHint": "Aggiungi un'email al tuo profilo per usare il metodo via email.", + "continue": "Continua", + "starting": "Avvio…", + "scanTitle": "Scansiona il codice QR", + "scanDescription": "Scansionalo con la tua app di autenticazione, poi inserisci il codice a 6 cifre mostrato.", + "manualKey": "Oppure inserisci questa chiave manualmente:", + "checkEmailTitle": "Controlla la tua email", + "checkEmailDescription": "Abbiamo inviato un codice a 6 cifre a {{email}}. Inseriscilo qui sotto.", + "resend": "Invia di nuovo", + "verifyEnable": "Verifica e attiva", + "verifying": "Verifica…" + }, + "actions": { + "cancel": "Annulla" + }, + "toast": { + "profileUpdated": "Profilo aggiornato", + "emailInUse": "Quell'email è già in uso", + "profileUpdateFailed": "Impossibile aggiornare il profilo", + "passwordsNoMatch": "Le password non corrispondono", + "passwordTooShort": "La password deve contenere almeno 8 caratteri", + "passwordChanged": "Password cambiata — le altre sessioni sono state disconnesse", + "currentPasswordWrong": "La password attuale è errata", + "passwordChangeFailed": "Impossibile cambiare la password", + "avatarTypeNotAllowed": "Tipo di immagine non consentito (usa PNG, JPEG, WEBP o GIF)", + "avatarTooLarge": "L'immagine è troppo grande (max 2MB)", + "avatarUpdated": "Avatar aggiornato", + "avatarUploadFailed": "Impossibile caricare l'avatar", + "avatarRemoved": "Avatar rimosso", + "avatarRemoveFailed": "Impossibile rimuovere l'avatar", + "sessionsLoadFailed": "Impossibile caricare le sessioni", + "sessionRevoked": "Sessione revocata", + "sessionRevokeFailed": "Impossibile revocare la sessione", + "othersSignedOut": "Altre sessioni disconnesse", + "othersRevokeFailed": "Impossibile revocare le sessioni", + "tfaEmailCodeSent": "Abbiamo inviato un codice a 6 cifre alla tua email", + "tfaNewCodeSent": "È stato inviato un nuovo codice", + "tfaWaitResend": "Attendi un momento prima di richiedere un nuovo codice", + "tfaResendFailed": "Impossibile inviare di nuovo il codice", + "tfaEnterCode": "Inserisci il codice a 6 cifre", + "tfaEnabled": "Autenticazione a due fattori attivata", + "tfaEnterPassword": "Inserisci la password attuale", + "tfaDisabled": "Autenticazione a due fattori disattivata", + "tfaDisableFailed": "Impossibile disattivare 2FA", + "tfaInvalidCode": "Codice non valido o scaduto", + "tfaAlreadyEnabled": "2FA è già attivo", + "tfaTooManyRequests": "Troppe richieste; riprova tra poco", + "tfaVerifyFailed": "Impossibile verificare il codice", + "genericError": "Qualcosa è andato storto", + "tfaMailUnavailable": "Il secondo fattore via e-mail richiede un server di posta. Configuralo in Impostazioni → Configurazione e-mail." + } }, - "forgot": { - "title": "Reimposta la password", - "subtitle": "Ti invieremo un link via email per impostare una nuova password.", - "emailLabel": "Email", - "submit": "Invia link", - "sent": "Se quell'email è registrata, il link di reimpostazione è in arrivo." + "home": { + "hero": { + "title": "Cosa vuoi sapere dai tuoi dati di sicurezza?", + "placeholder": "Indaga su Scattered Spider, ci riguarda?, siamo mai stati colpiti?, crea una regola di rilevamento e mantienila aggiornata.", + "send": "Invia", + "suggestions": { + "threatHunt": "Caccia alle minacce", + "observableTriage": "Triage degli osservabili", + "writeRule": "Scrivi una regola", + "systemStatus": "Stato attuale del sistema" + } + }, + "kpis": { + "alerts24h": "Avvisi (24 h)", + "openIncidents": "Incidenti aperti", + "openIncidentsSub": "attualmente aperti", + "highSeverity24h": "Gravità alta (24 h)", + "highSeveritySub": "su {{n}} avvisi", + "activePlaybooks": "Playbook attivi", + "activePlaybooksSub": "abilitati" + }, + "datasources": { + "title": "Origini dati", + "viewAll": "Vedi tutto", + "ofTotal": "su {{n}}", + "datasources": "origini dati", + "sendingData": "che inviano dati", + "totalEvents": "Eventi totali", + "noData": "Nessun dato di ingest in questo intervallo" + }, + "span": { + "recent": "intervallo recente", + "days_one": "ultimo {{count}} giorno", + "days_other": "ultimi {{count}} giorni", + "hours": "ultime {{n}} h" + }, + "mitre": { + "title": "Principali tecniche MITRE ATT&CK", + "explore": "Esplora", + "empty": "Nessun avviso con tecnica assegnata" + }, + "assets": { + "title": "Asset più presi di mira", + "viewAll": "Vedi tutto", + "asset": "Asset", + "alerts": "Avvisi", + "empty": "Nessun asset preso di mira negli avvisi recenti" + }, + "compliance": { + "title": "Punteggio di conformità", + "reports": "Report", + "empty": "Nessun report di conformità ancora generato" + }, + "health": { + "title": "Stato del sistema", + "details": "Dettagli", + "services": { + "backend": "API backend", + "opensearch": "Cluster OpenSearch", + "socai": "Motore SOC-AI" + }, + "detail": { + "noClusterInfo": "nessuna informazione sul cluster", + "disabled": "disabilitato", + "tools": "{{n}} strumenti", + "unreachable": "irraggiungibile", + "pending": "…" + } + } }, - "errors": { - "tooManyAttempts": "Troppi tentativi. Riprova tra qualche minuto.", - "deactivated": "Questo account è disattivato.", - "invalidCredentials": "Credenziali non valide.", - "codeExpired": "Questo codice è scaduto. Accedi di nuovo.", - "loginFailed": "Accesso non riuscito. Riprova.", - "invalidCode": "Codice non valido o scaduto.", - "verifyFailed": "Verifica non riuscita. Riprova.", - "resetFailed": "Impossibile inviare l'email di reimpostazione. Riprova.", - "ssoFailed": "L'accesso unico non è stato completato. Riprova o usa la tua password." - } - }, - "profile": { - "hero": { - "administrator": "Amministratore", - "changeAvatar": "Cambia avatar", - "removeAvatar": "Rimuovi avatar" + "nav": { + "home": "Home", + "dashboards": "Dashboard", + "dashboardList": "Elenco dashboard", + "visualizationList": "Widget", + "newDashboard": "Nuova dashboard", + "newVisualization": "Nuovo widget", + "threatManagement": "Gestione minacce", + "alerts": "Avvisi", + "incidents": "Incidenti", + "adversaryView": "Vista avversari", + "soar": "SOAR", + "flows": "Flussi", + "executionHistory": "Cronologia esecuzioni", + "interactiveConsole": "Console interattiva", + "logExplorer": "Esplora log", + "userAuditor": "Auditor utenti", + "threatIntelligence": "Intelligence sulle minacce", + "threat-intel": { + "indicators": "Indicatori", + "analyzt": "Analista IA", + "triage": "Triage", + "report": "Report" + }, + "compliance": "Conformità", + "configure": "Configura", + "dataSources": "Origini dati", + "integrations": "Integrazioni", + "alertingRules": "Regole di avviso", + "dataProcessing": "Elaborazione dati", + "team": "Team", + "settings": "Impostazioni", + "back": "Indietro", + "regexPatterns": "Espressioni regolari", + "taggingRules": "Regole di etichettatura", + "parsingFilters": "Pipeline", + "overview": "Panoramica", + "tenants": "Tenant", + "openMenu": "Apri menu", + "closeMenu": "Chiudi menu", + "liveOps": "Operazioni live" + }, + "dashboards": { + "title": "Dashboard", + "subtitle": "Sfoglia e modifica dashboard interattive.", + "list": { + "title": "Dashboard", + "create": "Nuova", + "searchPlaceholder": "Cerca dashboard…", + "loading": "Caricamento delle dashboard…", + "empty": "Nessuna dashboard ancora.", + "rename": "Rinomina", + "delete": "Elimina" + }, + "actions": { + "edit": "Modifica", + "editWithAi": "Modifica con l'IA" + }, + "refresh": { + "title": "Aggiornamento automatico", + "options": { + "off": "Disattivato", + "10s": "10s", + "30s": "30s", + "1m": "1m", + "5m": "5m", + "15m": "15m" + } + }, + "editor": { + "editing": "In modifica", + "addWidget": "Aggiungi widget", + "save": "Salva", + "discard": "Annulla", + "newTitle": "Nuovo widget", + "newSubtitle": "Scegli un tipo di grafico, una fonte di dati e modellalo visivamente. L'SQL viene generato automaticamente.", + "editTitle": "Modifica widget", + "editSubtitle": "Modifica la definizione del grafico. Le modifiche si applicano ovunque questo widget sia usato.", + "loading": "Caricamento del widget…", + "notFoundTitle": "Widget non trovato", + "notFoundSubtitle": "Potrebbe essere stata eliminata oppure non hai i permessi per accedervi.", + "backToDashboard": "Torna alla dashboard", + "chartType": { + "title": "Tipo di grafico" + }, + "chartTypes": { + "bar": { + "label": "Barre", + "description": "Confronta valori tra categorie." + }, + "line": { + "label": "Linea", + "description": "Tendenze lungo un asse ordinato." + }, + "area": { + "label": "Area", + "description": "Linea riempita — enfatizza il volume." + }, + "pie": { + "label": "Torta", + "description": "Quota sul totale per categoria." + }, + "metric": { + "label": "Metrica", + "description": "Un singolo valore scalare." + }, + "table": { + "label": "Tabella", + "description": "Righe aggregate." + }, + "list": { + "label": "Elenco", + "description": "Righe grezze, non aggregate." + }, + "region_map": { + "label": "Mappa di coordinate", + "description": "Posiziona indicatori su un planisfero usando coordinate lat/lon." + }, + "text": { + "label": "Testo", + "description": "Testo libero o semplice output per riga." + } + }, + "dataSource": { + "title": "Quali dati?", + "dataset": "Set di dati", + "noDatasetHint": "Scegli un set di dati per abilitare condizioni e raggruppamento." + }, + "widgetTitle": { + "label": "Titolo", + "placeholder": "Facoltativo — predefinito il tipo di grafico" + }, + "dataset": { + "placeholder": "Seleziona un set di dati…", + "loading": "Caricamento dei set di dati…" + }, + "filters": { + "title": "Includi solo eventi in cui…", + "empty": "Nessuna condizione: vengono inclusi tutti gli eventi dell’intervallo di tempo.", + "add": "Aggiungi condizione", + "remove": "Rimuovi", + "field": "Campo", + "fieldPlaceholder": "es. host.name", + "operator": "Operatore", + "value": "Valore", + "valuePlaceholder": "Valore", + "from": "Da", + "to": "A", + "noValue": "Nessun valore richiesto", + "listPlaceholder": "Valori separati da virgola" + }, + "operators": { + "IS": "è", + "IS_NOT": "non è", + "IS_ONE_OF_TERMS": "è uno tra", + "IS_GREATER_THAN": "è maggiore di", + "IS_LESS_THAN_OR_EQUALS": "è minore o uguale a", + "IS_BETWEEN": "è compreso tra", + "CONTAIN": "contiene", + "DOES_NOT_CONTAIN": "non contiene", + "START_WITH": "inizia con", + "ENDS_WITH": "termina con", + "EXIST": "esiste", + "DOES_NOT_EXIST": "non esiste" + }, + "dimension": { + "title": "Raggruppa per", + "field": "Campo", + "placeholder": "Scegli un campo per raggruppare…" + }, + "table": { + "hint": "Mostra tutti i campi dei record. Aggiungi colonne per sceglierne alcune.", + "columnsTitle": "Colonne", + "allColumns": "Verranno mostrate tutte le colonne. Aggiungi campi per sceglierne di specifiche.", + "addColumn": "Aggiungi una colonna…", + "removeColumn": "Rimuovi colonna" + }, + "chartPreview": { + "title": "Anteprima del grafico", + "noQuery": "Scegli un set di dati per vedere l’anteprima.", + "error": "La query di anteprima non è andata a buon fine." + }, + "chartTypeChip": { + "label": "Grafico:" + }, + "chartTypeModal": { + "title": "Scegli un tipo di grafico", + "subtitle": "Scegli come visualizzare i dati. Potrai cambiarlo in seguito.", + "confirm": "Continua", + "swapTitle": "Cambia tipo di grafico", + "swapConfirm": "Applica" + }, + "saveVisualization": "Salva widget", + "fieldSelect": { + "loading": "Caricamento dei campi…", + "choose": "Scegli un campo…" + }, + "toast": { + "notReady": "Scegli un set di dati e un campo per la suddivisione prima di salvare." + }, + "breakdown": { + "title": "Suddividi per", + "topValuesTable": "Tabella dei valori principali", + "time": "Nel tempo", + "field": "Valori più frequenti", + "interval": "Dimensione dell'intervallo", + "intervalAuto": "Automatico", + "limit": "Quanti", + "limitPlaceholder": "Predefinito (50)", + "splitHint": "Facoltativo: una linea per ogni valore di questo campo." + }, + "editFilters": "Edit filters" + }, + "grid": { + "empty": "Questa dashboard non ha ancora widget.", + "missingVisualization": "Widget non disponibile", + "unknownVisualization": "Widget" + }, + "widget": { + "renderError": "Impossibile renderizzare questo widget.", + "count": "Conteggio", + "loading": "Caricamento dei dati…", + "queryError": "Impossibile caricare i dati del widget.", + "noData": "Nessun dato per l'intervallo di tempo selezionato.", + "regionMapEmpty": "Nessun punto con lat/lon validi.", + "regionMapShapeHint": "L'SQL deve restituire le colonne di latitudine e longitudine (oppure un array value [lat, lon, count]).", + "regionMapUnnamed": "(senza nome)", + "regionMapValue": "valore: {{value}}", + "editAriaLabel": "Modifica widget", + "removeAriaLabel": "Rimuovi widget", + "moveBack": "Sposta indietro", + "moveForward": "Sposta avanti", + "width": "Larghezza", + "height": "Altezza", + "widthSmall": "1 col", + "widthMedium": "2 col", + "widthLarge": "3 col", + "heightNormal": "Normale", + "heightTall": "Alta", + "incompleteSpec": "A questo widget manca una parte della domanda." + }, + "form": { + "createTitle": "Nuova dashboard", + "renameTitle": "Modifica dashboard", + "name": "Nome", + "namePlaceholder": "es. Panoramica di rete", + "description": "Descrizione", + "descriptionPlaceholder": "Facoltativo", + "cancel": "Annulla", + "create": "Crea", + "save": "Salva" + }, + "confirm": { + "deleteTitle": "Elimina dashboard", + "delete": "Eliminare la dashboard «{{name}}»? Questa azione è irreversibile.", + "deleteWidgetsTitle": "Elimina widget", + "deleteWidgets_one": "Eliminare questo widget? Questa azione è irreversibile.", + "deleteWidgets_other": "Eliminare {{count}} widget? Questa azione è irreversibile.", + "dismissTitle": "Rimuovi dashboard", + "dismiss": "Rimuovere la dashboard predefinita \"{{name}}\"? Potrai crearne una nuova a partire da questa con \"Nuova\" → \"Da una esistente\"." + }, + "page": { + "noSelection": "Scegli una dashboard dall'elenco, oppure creane una per iniziare.", + "loading": "Caricamento dei widget…" + }, + "toast": { + "created": "Dashboard creata.", + "createFailed": "Impossibile creare la dashboard.", + "updated": "Dashboard aggiornata.", + "updateFailed": "Impossibile aggiornare la dashboard.", + "deleted": "Dashboard eliminata.", + "deleteFailed": "Impossibile eliminare la dashboard.", + "layoutSaved": "Layout salvato.", + "layoutSaveFailed": "Impossibile salvare il layout.", + "visualizationCreated": "Widget creato.", + "visualizationCreateFailed": "Impossibile creare il widget.", + "visualizationUpdated": "Widget aggiornato.", + "visualizationUpdateFailed": "Impossibile aggiornare il widget.", + "visualizationDeleted": "Widget eliminato.", + "visualizationDeleteFailed": "Impossibile eliminare il widget.", + "filterCreated": "Filtro creato.", + "filterUpdated": "Filtro aggiornato.", + "filterDeleted": "Filtro eliminato.", + "filterCreateFailed": "Impossibile creare il filtro.", + "filterUpdateFailed": "Impossibile aggiornare il filtro.", + "filterDeleteFailed": "Impossibile eliminare il filtro.", + "filtersSaved": "Filters saved.", + "filtersSaveFailed": "Could not save filters." + }, + "newDashboard": { + "title": "Nuova dashboard", + "subtitle": "Crea una dashboard vuota. Potrai aggiungere widget dopo averla salvata.", + "modeManual": "Crea manualmente", + "modeAi": "Con l'IA", + "aiLocked": "Attiva SOC-AI e configuralo per usare questa funzione.", + "aiDescriptionLabel": "Cosa deve mostrare questa dashboard?", + "aiDescriptionPlaceholder": "es. Accessi falliti per paese, ultimi 7 giorni", + "aiCreate": "Crea con l'IA", + "aiOpenerWithDetails": "Crea una dashboard chiamata \"{{name}}\" che mostri: {{description}}" + }, + "newVisualization": { + "title": "Nuovo widget", + "subtitle": "Definisci un grafico riutilizzabile partendo da una query SQL e da una configurazione ECharts.", + "sqlQuery": "Query SQL", + "sqlQueryPlaceholder": "SELECT bucket, count(*) FROM logs GROUP BY bucket", + "sqlQueryHint": "Usa i segnaposto timeFilter, from e to (tra doppie parentesi graffe) per applicare il selettore temporale al rendering.", + "config": "Configurazione del grafico (opzione ECharts, JSON)", + "configHint": "Deve essere un JSON valido. Le righe dell'SQL sono esposte come `dataset.source` — collega le tue serie con `encode`.", + "configError": "JSON non valido: {{error}}" + }, + "visualizationList": { + "title": "Widget", + "subtitle": "{{count}} widget disponibili.", + "subtitleFiltered": "Visualizzate {{shown}} su {{total}}.", + "create": "Nuova", + "searchPlaceholder": "Cerca widget…", + "loading": "Caricamento dei widget…", + "empty": "Nessun widget ancora.", + "emptyFiltered": "Nessun widget corrisponde ai filtri attuali.", + "delete": "Elimina", + "deleteTitle": "Elimina widget", + "confirmDelete": "Eliminare il widget «{{name}}»? Questa azione è irreversibile.", + "filters": { + "search": "Cerca", + "chartType": "Tipo di grafico", + "allChartTypes": "Tutti i tipi di grafico", + "source": "Fonte", + "allSources": "Tutte le fonti", + "createdAt": "Creata", + "modifiedAt": "Modificata", + "createdRangeTitle": "Intervallo personalizzato — Creazione", + "modifiedRangeTitle": "Intervallo personalizzato — Modifica", + "pickRange": "Scegli un intervallo", + "datePresets": { + "all": "Tutti i periodi", + "today": "Oggi", + "last7": "Ultimi 7 giorni", + "last30": "Ultimi 30 giorni", + "lastYear": "Ultimo anno", + "custom": "Intervallo personalizzato" + }, + "clear": "Cancella filtri" + }, + "col": { + "name": "Nome", + "chartType": "Tipo di grafico", + "source": "Fonte", + "description": "Descrizione", + "created": "Creata", + "modified": "Modificata" + } + }, + "tabs": { + "dashboards": "Dashboard", + "visualizations": "Widget", + "newDashboard": "Nuova dashboard", + "unsetDefault": "Rimuovi predefinita", + "options": "Opzioni" + }, + "picker": { + "none": "Seleziona dashboard", + "search": "Cerca dashboard…", + "new": "Nuova dashboard", + "setDefault": "Imposta come predefinita", + "empty": "Nessuna dashboard" + }, + "empty": { + "title": "Ancora nessuna dashboard", + "body": "Crea la tua prima dashboard per vedere i tuoi dati di sicurezza a colpo d’occhio.", + "cta": "Crea dashboard" + }, + "filters": { + "addTitle": "Aggiungi filtro", + "editTitle": "Modifica filtro", + "removeTitle": "Rimuovi filtro", + "removeConfirm": "Rimuovere il filtro \"{{label}}\"? Questa azione è irreversibile.", + "remove": "Rimuovi", + "editAria": "Modifica filtro", + "removeAria": "Rimuovi filtro", + "saving": "Salvataggio…", + "addChip": "Aggiungi filtro", + "chooseValue": "Choose…", + "selected": "selected", + "loading": "Loading values…", + "searchPlaceholder": "Search values…", + "noValues": "No values available.", + "loadError": "Could not load values.", + "clear": "Clear", + "editorTitle": "Dashboard filters", + "editorHint": "Add dropdown chips that filter every widget on this dashboard.", + "emptyEditor": "No filter chips yet. Add one to get started.", + "cancel": "Cancel", + "save": "Save", + "field": { + "dataset": "Data set", + "field": "Field", + "chooseField": "Choose a field…", + "label": "Label", + "labelPlaceholder": "e.g. Host", + "placeholder": "Placeholder", + "placeholderPlaceholder": "e.g. Pick a host", + "multiple": "Multiple", + "searchable": "Searchable" + } + }, + "duplicate": { + "copyName": "{{name}} (copia)" + } }, - "personal": { - "title": "Informazioni personali", - "description": "Aggiorna il tuo nome e i tuoi contatti.", - "firstName": "Nome", - "lastName": "Cognome", - "email": "Email", - "language": "Lingua", - "languageHint": "Usata per l'interfaccia del pannello.", - "systemDefault": "Predefinito del sistema", - "username": "Nome utente", - "usernameHint": "Il nome utente non può essere modificato.", - "reset": "Reimposta", - "save": "Salva modifiche", - "saving": "Salvataggio…", - "name": "Nome" + "settings": { + "title": "Impostazioni", + "license": "Licenza", + "notifications": "Notifiche", + "connectionKey": "Chiave di connessione", + "dataRetention": "Conservazione dati", + "indices": "Indici", + "theme": "Tema", + "branding": "Brand", + "apiKeys": "Chiavi API", + "identityProviders": "Provider di identità", + "email": "Configurazione email", + "dateFormat": "Formato data", + "language": "Lingua", + "auditLogs": "Log di audit", + "about": "Informazioni", + "socAi": "SOC-AI", + "supportAccess": "Accesso di supporto", + "threatwinds": "Integrazione ThreatWinds" + }, + "topbar": { + "theme": { + "light": "Modalità chiara", + "dark": "Modalità scura" + }, + "manageLicense": "Gestisci licenza", + "profile": { + "profile": "Profilo", + "license": "Licenza", + "logout": "Esci" + } }, - "password": { - "title": "Password", - "description": "Usa una password forte che non riutilizzi da nessun'altra parte.", - "current": "Password attuale", - "new": "Nuova password", - "newHint": "Almeno 8 caratteri.", - "confirm": "Conferma nuova password", - "update": "Aggiorna password", - "updating": "Aggiornamento…" + "notifications": { + "title": "Notifiche", + "markAllRead": "Segna tutte come lette", + "empty": "Non hai notifiche.", + "viewAll": "Vedi tutte", + "markRead": "Segna come letta", + "markUnread": "Segna come non letta", + "delete": "Elimina", + "subtitle": "{{total}} in totale · {{unread}} non lette", + "allCaughtUp": "Tutto in ordine.", + "loadFailed": "Impossibile caricare le notifiche." }, - "sessions": { - "title": "Sessioni attive", - "description": "Dispositivi attualmente connessi al tuo account.", - "loading": "Caricamento sessioni…", - "empty": "Nessuna sessione attiva.", - "thisDevice": "Questo dispositivo", - "unknownIp": "IP sconosciuto", - "unknownDevice": "Dispositivo sconosciuto", - "deviceLabel": "{{browser}} su {{os}}", - "signedIn": "Accesso {{time}}", - "revoke": "Revoca", - "revoking": "Revoca in corso…", - "signOutOthers": "Disconnetti tutte le altre sessioni", - "signingOut": "Disconnessione…" + "pagination": { + "perPage": "Per pagina", + "pageOf": "Pagina {{page}} di {{total}}", + "previous": "Precedente", + "next": "Successiva" }, - "tfa": { - "title": "Autenticazione a due fattori", - "description": "Aggiungi un ulteriore livello di sicurezza al tuo account.", - "loading": "Caricamento…", - "methodTotp": "App di autenticazione", - "methodEmail": "Codice via email", - "onTitle": "L'autenticazione a due fattori è attiva", - "method": "Metodo: {{method}}", - "configured": "Configurato", - "disable": "Disattiva", - "disableTitle": "Disattiva l'autenticazione a due fattori", - "disableDescription": "Inserisci la password attuale per confermare. Il tuo account si baserà solo sulla password in seguito.", - "currentPasswordPlaceholder": "Password attuale", - "disableConfirm": "Disattiva 2FA", - "disabling": "Disattivazione…", - "offTitle": "L'autenticazione a due fattori è disattivata", - "status": "Stato:", - "notConfigured": "Non configurato", - "enable": "Attiva", - "chooseMethod": "Scegli un metodo", - "totpDesc": "Usa Google Authenticator, 1Password, ecc. Consigliato.", - "emailDesc": "Ricevi un codice a 6 cifre via email all'accesso.", - "noEmailHint": "Aggiungi un'email al tuo profilo per usare il metodo via email.", - "continue": "Continua", - "starting": "Avvio…", - "scanTitle": "Scansiona il codice QR", - "scanDescription": "Scansionalo con la tua app di autenticazione, poi inserisci il codice a 6 cifre mostrato.", - "manualKey": "Oppure inserisci questa chiave manualmente:", - "checkEmailTitle": "Controlla la tua email", - "checkEmailDescription": "Abbiamo inviato un codice a 6 cifre a {{email}}. Inseriscilo qui sotto.", - "resend": "Invia di nuovo", - "verifyEnable": "Verifica e attiva", - "verifying": "Verifica…" + "license": { + "title": "Licenza", + "subtitle": "La tua edizione, funzionalità e file di licenza.", + "loading": "Caricamento licenza…", + "loadError": "Impossibile caricare le informazioni sulla licenza.", + "statusLabel": "Stato", + "status": { + "community": "Community", + "active": "Attiva", + "expiring": "In scadenza", + "expired": "Scaduta" + }, + "edition": "Edizione", + "enterprise": "Enterprise", + "community": "Community", + "editionLine": "Edizione {{edition}}", + "datasourceLimit": "Limite origini dati", + "unlimited": "Illimitato", + "mssp": "MSSP / multi-tenant", + "enabled": "Attivato", + "licenseType": "Tipo di licenza", + "instanceId": "ID istanza", + "enterpriseUnlocked": "Funzionalità Enterprise sbloccate", + "validUntil": "Valida fino al", + "noExpiry": "Nessuna scadenza", + "timeRemaining": "Tempo rimanente", + "expiredAgo": "Scaduta {{days}}g fa", + "daysShort": "{{days}}g", + "msspShort": "MSSP", + "communityEdition": "Edizione Community", + "communityBlurb": "Gratuita e open source. Carica una licenza Enterprise qui sotto per sbloccare multi-tenancy, SSO, limiti di origini dati più elevati e conformità avanzata.", + "upgrade": "Passa a Enterprise", + "uploadTitle": "Carica una licenza", + "uploadBlurb": "Installa o sostituisci il file LICENSE firmato. Il server verifica firma e scadenza prima di applicarlo. Solo admin.", + "installLicense": "Installa licenza", + "chooseFile": "Scegli file", + "noFileSelected": "Nessun file selezionato", + "toast": { + "installed": "Licenza installata — edizione {{edition}}.", + "adminRequired": "Sono richiesti privilegi di amministratore per caricare una licenza.", + "invalid": "File di licenza non valido o scaduto.", + "installFailed": "Impossibile installare la licenza." + }, + "ingestLimit": "Volume di ingest", + "notMetered": "Non misurato", + "gbPerMonth": "{{gb}} GB/mese" + }, + "audit": { + "title": "Log di audit", + "subtitle": "Registro di ogni azione rilevante per la sicurezza.", + "totalEntries": "{{total}} voci in totale.", + "loadError": "Impossibile caricare il log di audit", + "stats": { + "totalEntries": "Voci totali", + "acrossAllTime": "Di tutto il periodo", + "successRate": "Tasso di successo", + "failuresOnPage_one": "{{count}} errore in questa pagina", + "failuresOnPage_other": "{{count}} errori in questa pagina", + "topAction": "Azione principale", + "onPage": "{{count}} in questa pagina", + "uniqueActors": "Attori unici", + "includingSystem": "Incluso il sistema" + }, + "filters": { + "title": "Filtri", + "clear": "Cancella", + "last24h": "Ultime 24h", + "failuresOnly": "Solo errori", + "authEvents": "Eventi di autenticazione", + "actionPrefix": "Prefisso azione", + "actionPlaceholder": "es. auth., user.update", + "status": "Stato", + "any": "Qualsiasi", + "resourceType": "Tipo di risorsa", + "resourceTypePlaceholder": "user, alert…", + "resourceId": "ID risorsa", + "user": "Utente", + "userPlaceholder": "login…" + }, + "statusValue": { + "success": "Successo", + "failure": "Errore" + }, + "table": { + "timestamp": "Data e ora", + "actor": "Attore", + "action": "Azione", + "resource": "Risorsa", + "status": "Stato", + "ip": "IP", + "loading": "Caricamento…", + "emptyTitle": "Nessuna voce corrisponde a questi filtri.", + "emptyHint": "Prova a cancellare i filtri o ad ampliare l'intervallo di date.", + "system": "sistema", + "view": "Visualizza" + }, + "drawer": { + "entry": "voce #{{id}}", + "overview": "Panoramica", + "raw": "JSON grezzo", + "error": "Errore", + "actor": "Attore", + "resource": "Risorsa", + "ip": "IP", + "userAgent": "User agent", + "session": "Sessione", + "metadata": "Metadati", + "copy": "Copia", + "copied": "Copiato", + "copyJson": "Copia JSON" + } }, - "actions": { - "cancel": "Annulla" + "team": { + "title": "Team", + "subtitle": "Gestisci gli utenti e i loro ruoli.", + "tabs": { + "members": "Membri", + "roles": "Ruoli e permessi" + }, + "toast": { + "rolesLoadFailed": "Impossibile caricare i ruoli", + "userLoadFailed": "Impossibile caricare l'utente", + "rolesUpdated": "Ruoli aggiornati", + "userReactivated": "Utente riattivato", + "userDeactivated": "Utente disattivato", + "tfaReset": "Autenticazione a due fattori reimpostata", + "invitationSent": "Invito inviato", + "loginOrEmailInUse": "Questo nome utente o email è già in uso", + "invalidRequest": "Richiesta non valida", + "noPermission": "Non hai il permesso di farlo", + "userNotFound": "Utente non trovato", + "operationFailed": "Operazione non riuscita", + "emailInUse": "Questa e-mail è già in uso", + "roleCreated": "Ruolo creato", + "roleUpdated": "Ruolo aggiornato", + "roleDeleted": "Ruolo eliminato", + "roleNameInUse": "Esiste già un ruolo con questo identificatore", + "roleImmutable": "I ruoli di sistema non possono essere modificati", + "permissionsLoadFailed": "Impossibile caricare i permessi", + "localUserCreated": "Utente locale creato" + }, + "members": { + "searchPlaceholder": "Cerca per nome o e-mail…", + "invite": "Invita utente", + "colUser": "Utente", + "colRoles": "Ruoli", + "col2fa": "2FA", + "colStatus": "Stato", + "loading": "Caricamento utenti…", + "loadFailed": "Impossibile caricare gli utenti.", + "retry": "Riprova", + "noSearchMatch": "Nessun utente corrisponde alla ricerca.", + "none": "Nessun utente ancora.", + "noRole": "nessuno", + "on": "Sì", + "off": "No", + "countLabel_one": "{{count}} utente · pagina {{page}} di {{pages}}", + "countLabel_other": "{{count}} utenti · pagina {{page}} di {{pages}}", + "federated": "SSO" + }, + "status": { + "inactive": "Inattivo", + "pendingPassword": "Password in sospeso", + "active": "Attivo", + "pending": "Invito in sospeso", + "suspended": "Sospeso" + }, + "drawer": { + "createdBy": "creato da {{actor}}", + "loading": "Caricamento…", + "profileTitle": "Profilo", + "profileSubtitle": "Solo l'utente può modificare questi dati, dal proprio profilo.", + "name": "Nome", + "username": "Nome utente", + "email": "Email", + "language": "Lingua", + "accountTitle": "Account", + "status": "Stato", + "statusActive": "Attivo", + "statusInactive": "Inattivo", + "tfa": "2FA", + "tfaEnabled": "Attiva", + "tfaNotConfigured": "Non configurato", + "resetTfa": "Reimposta", + "resetTfaHint": "Disattiva il 2FA di questo utente così potrà riconfigurarlo al prossimo accesso", + "resetTfaConfirmTitle": "Reimpostare l'autenticazione a due fattori?", + "resetTfaConfirmBody": "Questo disattiva il 2FA di {{name}}. Accederà solo con la password e potrà riconfigurarlo dal proprio profilo.", + "resetTfaConfirm": "Reimposta 2FA", + "pendingPasswordNote": "Usa ancora la password temporanea (invito non completato).", + "lastModified": "Modificato {{time}}", + "rolesTitle": "Ruoli", + "rolesSubtitle": "I ruoli concedono permessi di modulo. Un utente può averne più di uno.", + "noRoleWarning": "Nessun ruolo assegnato — l'utente non avrà accesso ai moduli.", + "deactivate": "Disattiva", + "reactivate": "Riattiva", + "waitingInvite": "In attesa che l'utente accetti l'invito.", + "cancel": "Annulla", + "saving": "Salvataggio…", + "saveRoles": "Salva ruoli", + "created": "creato {{time}}", + "pendingNote": "L'invito non è ancora stato accettato.", + "federatedNote": "Accede tramite un provider di identità." + }, + "invite": { + "title": "Invita utente", + "description": "L'account viene creato inattivo. L'utente riceve un'e-mail per impostare la password e attivarlo.", + "username": "Nome utente", + "usernameHint": "Almeno 3 caratteri.", + "email": "Email", + "firstName": "Nome", + "lastName": "Cognome", + "roles": "Ruoli", + "cancel": "Annulla", + "sending": "Invio…", + "send": "Invia invito", + "name": "Nome", + "emailHint": "È l'indirizzo con cui accederà.", + "localDescription": "L'account viene creato con una password e attivato immediatamente. Non viene inviata alcuna e-mail.", + "modeInvite": "Invita utente", + "modeLocal": "Crea utente locale", + "passwordLabel": "Password", + "passwordPlaceholder": "Imposta una password forte", + "localUserNote": "Questo utente non riceverà un'e-mail e verrà attivato automaticamente.", + "createLocal": "Crea utente", + "passwordRules": { + "length": "Almeno 8 caratteri", + "case": "Almeno un carattere maiuscolo e uno minuscolo", + "special": "Almeno un carattere speciale" + }, + "emailInvalid": "Inserisci un indirizzo e-mail valido" + }, + "rolePicker": { + "none": "Nessun ruolo disponibile." + }, + "roles": { + "loading": "Caricamento ruoli…", + "loadFailed": "Impossibile caricare i permessi dei ruoli.", + "readonlyNote": "I ruoli e i loro permessi sono definiti dal sistema e di sola lettura. Assegnali agli utenti dalla scheda Membri.", + "permissionsCount_one": "{{count}} permesso", + "permissionsCount_other": "{{count}} permessi", + "modulesCount_one": "{{count}} modulo", + "modulesCount_other": "{{count}} moduli", + "matrixTitle": "Matrice dei permessi", + "matrixSubtitle": "Cosa può fare ogni ruolo, per modulo.", + "permission": "Permesso", + "systemNote": "I ruoli di sistema fanno parte della piattaforma e non sono modificabili. Quelli che crei appartengono a questo tenant.", + "newRole": "Nuovo ruolo", + "edit": "Modifica", + "delete": "Elimina", + "systemBadge": "Sistema", + "createTitle": "Nuovo ruolo", + "editTitle": "Modifica ruolo", + "editorSubtitle": "Scegli cosa può fare questo ruolo. Un utente può averne più di uno.", + "nameLabel": "Identificatore", + "nameHint": "Usato nel codice e nell'API. Ad esempio ROLE_AUDITOR.", + "displayNameLabel": "Nome visualizzato", + "descriptionLabel": "Descrizione", + "permissionsLabel": "Permessi", + "selectedCount": "{{count}} selezionati", + "toggleAll": "tutti", + "loadingPermissions": "Caricamento permessi…", + "save": "Salva ruolo", + "deleteConfirmTitle": "Eliminare questo ruolo?", + "deleteConfirmBody": "{{name}} verrà rimosso. Chi ha solo questo ruolo resterà senza accesso ai moduli." + }, + "langDefault": "Predefinito di sistema", + "relative": { + "justNow": "proprio ora", + "minutesAgo": "{{count}} min fa", + "hoursAgo": "{{count}} h fa", + "daysAgo": "{{count}} g fa" + }, + "roleNames": { + "ROLE_ADMIN": "Amministratore", + "ROLE_USER": "Utente" + }, + "roleDescriptions": { + "ROLE_ADMIN": "Accesso completo a tutte le risorse", + "ROLE_USER": "Utente standard con accesso in lettura a livello di modulo" + }, + "actions": { + "read": "Lettura", + "write": "Scrittura", + "delete": "Eliminazione" + }, + "resources": { + "adaudit": "Audit AD", + "alerts": "Avvisi", + "audit": "Registro di audit", + "compliance": "Conformità", + "config": "Configurazione", + "dashboards": "Dashboard", + "datasources": "Datasources", + "eventprocessing": "Elaborazione eventi", + "idp": "Provider di identità", + "incidents": "Incidenti", + "integrations": "Integrazioni", + "loganalyzer": "Analizzatore di log", + "opensearch": "OpenSearch", + "roles": "Ruoli", + "soar": "SOAR", + "users": "Utenti", + "notifications": "Notifiche", + "socai": "SOC AI", + "tenant": "Tenant", + "threatintel": "Threat intelligence" + } }, - "toast": { - "profileUpdated": "Profilo aggiornato", - "emailInUse": "Quell'email è già in uso", - "profileUpdateFailed": "Impossibile aggiornare il profilo", - "passwordsNoMatch": "Le password non corrispondono", - "passwordTooShort": "La password deve contenere almeno 8 caratteri", - "passwordChanged": "Password cambiata — le altre sessioni sono state disconnesse", - "currentPasswordWrong": "La password attuale è errata", - "passwordChangeFailed": "Impossibile cambiare la password", - "avatarTypeNotAllowed": "Tipo di immagine non consentito (usa PNG, JPEG, WEBP o GIF)", - "avatarTooLarge": "L'immagine è troppo grande (max 2MB)", - "avatarUpdated": "Avatar aggiornato", - "avatarUploadFailed": "Impossibile caricare l'avatar", - "avatarRemoved": "Avatar rimosso", - "avatarRemoveFailed": "Impossibile rimuovere l'avatar", - "sessionsLoadFailed": "Impossibile caricare le sessioni", - "sessionRevoked": "Sessione revocata", - "sessionRevokeFailed": "Impossibile revocare la sessione", - "othersSignedOut": "Altre sessioni disconnesse", - "othersRevokeFailed": "Impossibile revocare le sessioni", - "tfaEmailCodeSent": "Abbiamo inviato un codice a 6 cifre alla tua email", - "tfaNewCodeSent": "È stato inviato un nuovo codice", - "tfaWaitResend": "Attendi un momento prima di richiedere un nuovo codice", - "tfaResendFailed": "Impossibile inviare di nuovo il codice", - "tfaEnterCode": "Inserisci il codice a 6 cifre", - "tfaEnabled": "Autenticazione a due fattori attivata", - "tfaEnterPassword": "Inserisci la password attuale", - "tfaDisabled": "Autenticazione a due fattori disattivata", - "tfaDisableFailed": "Impossibile disattivare 2FA", - "tfaInvalidCode": "Codice non valido o scaduto", - "tfaAlreadyEnabled": "2FA è già attivo", - "tfaTooManyRequests": "Troppe richieste; riprova tra poco", - "tfaVerifyFailed": "Impossibile verificare il codice", - "genericError": "Qualcosa è andato storto", - "tfaMailUnavailable": "Il secondo fattore via e-mail richiede un server di posta. Configuralo in Impostazioni → Configurazione e-mail." - } - }, - "home": { - "hero": { - "title": "Cosa vuoi sapere dai tuoi dati di sicurezza?", - "placeholder": "Indaga su Scattered Spider, ci riguarda?, siamo mai stati colpiti?, crea una regola di rilevamento e mantienila aggiornata.", - "send": "Invia", - "suggestions": { - "threatHunt": "Caccia alle minacce", - "observableTriage": "Triage degli osservabili", - "writeRule": "Scrivi una regola", - "systemStatus": "Stato attuale del sistema" - } + "apiKeys": { + "title": "Chiavi API", + "subtitle": "Token di accesso programmatico per l’API di UTMStack.", + "new": "Nuova chiave API", + "searchPlaceholder": "Cerca per nome o IP consentito…", + "refresh": "Aggiorna", + "loading": "Caricamento chiavi API…", + "loadFailed": "Impossibile caricare le chiavi API.", + "retry": "Riprova", + "noSearchMatch": "Nessuna chiave API corrisponde alla ricerca.", + "empty": "Ancora nessuna chiave API. Creane una per iniziare.", + "anyIp": "Qualsiasi IP", + "never": "Mai", + "count_one": "{{count}} chiave · pagina {{page}} di {{pages}}", + "count_other": "{{count}} chiavi · pagina {{page}} di {{pages}}", + "enterprise": { + "title": "Le chiavi API sono una funzione Enterprise", + "body": "Emetti, limita e ruota le chiavi API per l’accesso programmatico all’API di UTMStack. Questa funzionalità è disponibile nell’edizione Enterprise.", + "upgrade": "Passa a Enterprise", + "manageLicense": "Gestisci la tua licenza" + }, + "col": { + "name": "Nome", + "allowedIps": "IP consentiti", + "created": "Creata", + "lastRotated": "Ultima rotazione", + "expires": "Scade", + "status": "Stato", + "actions": "Azioni" + }, + "status": { + "active": "Attiva", + "expiring": "In scadenza", + "expired": "Scaduta" + }, + "action": { + "rotate": "Ruota", + "edit": "Modifica", + "delete": "Elimina" + }, + "dialog": { + "editTitle": "Modifica chiave API", + "newTitle": "Nuova chiave API", + "name": "Nome", + "namePlaceholder": "ci-pipeline", + "allowedIps": "IP consentiti", + "allowedIpsHint": "Separati da virgola. Lascia vuoto per consentire qualsiasi IP.", + "expires": "Scade", + "expiresHint": "Lascia vuoto per una chiave che non scade mai.", + "secretNote": "Il token segreto viene mostrato una sola volta, subito dopo la creazione. Copialo allora — non può essere recuperato in seguito (solo ruotato).", + "cancel": "Annulla", + "saving": "Salvataggio…", + "saveChanges": "Salva modifiche", + "createKey": "Crea chiave" + }, + "confirm": { + "deleteTitle": "Elimina chiave API", + "rotateTitle": "Ruota chiave API", + "deleteBody": "Eliminare {{name}}? Qualsiasi client che la utilizza perderà immediatamente l’accesso. Questa azione non può essere annullata.", + "rotateBody": "Ruotare {{name}}? Viene emesso un nuovo segreto e quello attuale smette di funzionare immediatamente. Il nuovo token viene mostrato una sola volta.", + "cancel": "Annulla", + "working": "In corso…", + "delete": "Elimina", + "rotate": "Ruota" + }, + "reveal": { + "title": "Chiave API creata", + "note": "Copia questo segreto ora — per {{name}}. Non verrà più mostrato. Se lo perdi, ruota la chiave.", + "copied": "Copiato", + "copy": "Copia", + "done": "Fatto" + }, + "toast": { + "updated": "Chiave API aggiornata", + "secretIssueFailed": "Chiave creata, ma non è stato possibile emettere il segreto. Usa Ruota per ottenerne uno.", + "deleted": "Chiave API eliminata" + }, + "error": { + "nameTaken": "Esiste già una chiave API con quel nome", + "enterpriseRequired": "Le chiavi API richiedono l’edizione Enterprise", + "notFound": "Chiave API non trovata", + "invalidRequest": "Richiesta non valida", + "failed": "Operazione non riuscita" + } }, - "kpis": { - "alerts24h": "Avvisi (24 h)", - "openIncidents": "Incidenti aperti", - "openIncidentsSub": "attualmente aperti", - "highSeverity24h": "Gravità alta (24 h)", - "highSeveritySub": "su {{n}} avvisi", - "activePlaybooks": "Playbook attivi", - "activePlaybooksSub": "abilitati" + "idp": { + "title": "Provider di identità", + "subtitle": "Single sign-on SAML 2.0 per la tua organizzazione.", + "add": "Aggiungi provider", + "enterprise": { + "title": "L'SSO è una funzione Enterprise", + "body": "Collega un provider di identità SAML 2.0 (Entra ID, Okta, Google Workspace…) per far accedere il tuo team con il tuo IdP. Il single sign-on è disponibile nell'edizione Enterprise.", + "upgrade": "Passa a Enterprise" + }, + "loading": "Caricamento provider di identità…", + "loadFailed": "Impossibile caricare i provider di identità.", + "retry": "Riprova", + "empty": { + "title": "Nessun provider di identità configurato", + "body": "Aggiungi un provider SAML 2.0 per far accedere il tuo team con il tuo IdP aziendale." + }, + "card": { + "enable": "Abilita", + "disable": "Disabilita", + "active": "Attivo", + "disabled": "Disabilitato", + "metadataUrl": "URL metadati", + "spEntityId": "SP Entity ID", + "spAcsUrl": "SP ACS URL", + "loginUrl": "URL di accesso", + "copy": "Copia", + "edit": "Modifica", + "delete": "Elimina", + "jit": "Provisioning", + "jitOn": "creates accounts on first sign-in", + "sync": "Roles", + "syncOn": "re-applied on every sign-in" + }, + "form": { + "addTitle": "Aggiungi provider di identità", + "editTitle": "Modifica provider di identità", + "name": "Nome", + "nameHint": "Univoco. Usato nell'URL SSO.", + "providerType": "Tipo di provider", + "providerTypeHint": "Un'etichetta, es. azure, okta, google.", + "metadataUrl": "URL metadati dell'IdP", + "spEntityId": "SP Entity ID", + "spAcsUrl": "SP ACS URL", + "certificate": "Certificato SP (PEM)", + "privateKey": "Chiave privata SP (PEM)", + "privateKeyHintEdit": "Lascia vuoto per mantenere la chiave salvata.", + "privateKeyHintCreate": "Obbligatoria. Salvata cifrata; non verrà più mostrata.", + "privateKeyUnchanged": "•••••••• (invariata)", + "active": "Attivo (mostra nella pagina di accesso)", + "cancel": "Annulla", + "saving": "Salvataggio…", + "save": "Salva modifiche", + "create": "Crea provider", + "issuer": "Issuer URL", + "issuerHint": "Discovery runs against this; the provider must serve /.well-known/openid-configuration under it.", + "clientId": "Client ID", + "redirectUrl": "Redirect URL", + "redirectUrlHint": "Register this exact URL with the provider.", + "host": "Host", + "port": "Port", + "startTls": "TLS", + "startTlsOn": "Use StartTLS", + "bindDn": "Bind DN", + "bindDnHint": "A service account that may search the directory.", + "baseDn": "Base DN", + "userFilter": "User filter", + "userFilterHint": "Must contain %s, where the address typed at login is placed.", + "emailAttribute": "Email attribute", + "nameAttribute": "Name attribute", + "groupAttribute": "Group attribute", + "provisioning": "Accounts and roles", + "provisioningHint": "What happens when someone the directory vouches for signs in.", + "jit": "Create the account on first sign-in", + "defaultRole": "Default role", + "defaultRoleHint": "Given when no group matches. Without one, an unmatched sign-in is refused.", + "noDefaultRole": "None", + "groupsAttribute": "Groups attribute", + "groupsAttributeHint": "Where the provider puts group membership.", + "syncRoles": "Re-apply roles on every sign-in", + "syncRolesHint": "Roles not in the mapping are removed, so a change in the directory reaches here. Without this, a demotion never arrives.", + "mappings": "Group to role", + "mappingsHint": "A directory group on the left, the role it grants on the right.", + "addMapping": "Add", + "noMappings": "No mappings. Everyone gets the default role.", + "groupPlaceholder": "SOC Analysts", + "pickRole": "Pick a role", + "secret.saml": "SP private key", + "secret.oidc": "Client secret", + "secret.ldap": "Bind password", + "secretHintCreate": "Stored encrypted and never shown again.", + "secretHintEdit": "Leave blank to keep the stored one.", + "secretUnchanged": "invariato", + "errors": { + "required": "Questo campo è obbligatorio.", + "url": "Deve essere un URL http(s) valido.", + "httpsUrl": "Deve essere un URL https valido.", + "hostname": "Immettere un host o un IP senza schema (es. ldap.esempio.it).", + "port": "La porta deve essere un numero intero tra 0 e 65535.", + "pemCertificate": "Non sembra un certificato PEM (manca -----BEGIN/END CERTIFICATE-----).", + "pemKey": "Non sembra una chiave privata PEM (manca -----BEGIN/END PRIVATE KEY-----).", + "userFilterPlaceholder": "Il filtro deve contenere %s, dove viene inserita l'indirizzo di accesso.", + "userFilterUnbalanced": "Parentesi non bilanciate: la ricerca non restituirà nulla.", + "nameFormat": "Usa lettere, numeri, punti, trattini o underscore (max 64). Compare nell'URL SSO, quindi niente spazi.", + "redirectUrl": "Deve essere un URL https valido oppure un URL http di loopback (localhost / 127.0.0.1 / [::1]).", + "entityId": "Deve essere un URI valido, es. https://utmstack.example.com/sp." + } + }, + "delete": { + "title": "Elimina provider di identità", + "body": "Eliminare {{name}}? Gli utenti non potranno più accedere tramite esso. L'operazione non può essere annullata.", + "cancel": "Annulla", + "deleting": "Eliminazione…", + "confirm": "Elimina" + }, + "toast": { + "enabled": "Provider abilitato", + "disabled": "Provider disabilitato", + "created": "Provider di identità creato", + "updated": "Provider di identità aggiornato", + "deleted": "Provider di identità eliminato", + "paidPlan": "L'SSO SAML richiede un piano a pagamento", + "enterpriseRequired": "L'SSO richiede l'edizione Enterprise", + "notFound": "Provider di identità non trovato", + "invalid": "Configurazione non valida", + "failed": "Operazione non riuscita" + }, + "providerType": { + "saml": "SAML 2.0", + "oidc": "OpenID Connect", + "ldap": "LDAP / Active Directory", + "comingSoon": "non ancora disponibile" + } }, - "datasources": { - "title": "Origini dati", - "viewAll": "Vedi tutto", - "ofTotal": "su {{n}}", - "datasources": "origini dati", - "sendingData": "che inviano dati", - "totalEvents": "Eventi totali", - "noData": "Nessun dato di ingest in questo intervallo" + "userAuditor": { + "title": "Auditor utenti", + "subtitle": "Account di Active Directory osservati nei tuoi log di sicurezza di Windows — rilevati da eventi di creazione, accesso ed eliminazione.", + "export": "Esporta", + "accountsChip": "{{count}} account", + "overview": { + "title": "Inventario account", + "active": "attivi", + "disabled": "disabilitati", + "deleted": "eliminati", + "seen24h": "{{count}} visti nelle ultime 24 ore", + "byDomain": "Per dominio", + "grouped": "{{count}} raggruppati", + "unassigned": "{{count}} non assegnati" + }, + "views": { + "all": "Tutti gli account", + "windows": "Windows", + "linux": "Linux", + "active": "Attivi", + "disabled": "Disabilitati", + "deleted": "Eliminati", + "service": "Account di servizio", + "stale": "Inattivi (30g+)", + "o365": "O365", + "azure": "Azure", + "gcp": "GCP", + "aws": "AWS" + }, + "searchPlaceholder": "Cerca per nome account o SID…", + "allTenants": "Tutti i tenant", + "filters": { + "add": "Aggiungi filtro", + "clearAll": "Cancella tutto", + "filterValues": "Filtra valori…", + "loadingValues": "Caricamento valori…", + "noValues": "Nessun valore trovato.", + "pickValue": "Scegli un valore per aggiungere il filtro.", + "empty": "(vuoto)", + "cancel": "Annulla", + "addBtn": "Aggiungi" + }, + "filterFields": { + "status": "Stato del ciclo di vita" + }, + "ops": { + "is": "è" + }, + "refresh": "Aggiorna", + "layout": { + "list": "Elenco", + "cards": "Schede" + }, + "list": { + "account": "Account", + "identity": "Identità", + "sid": "SID", + "status": "Stato", + "lastLogon": "Ultimo accesso", + "lastSeen": "Visto l’ultima volta", + "tenant": "Tenant", + "accountId": "ID account", + "identityGroup": "Gruppo identità" + }, + "status": { + "active": "Attivo", + "disabled": "Disabilitato", + "deleted": "Eliminato" + }, + "badge": { + "service": "servizio", + "stale": "inattivo" + }, + "empty": "Nessun account corrisponde a questa vista.", + "loadError": "Impossibile caricare gli account AD.", + "retry": "Riprova", + "card": { + "lastLogon": "Ultimo accesso" + }, + "pageInfo": "{{from}}–{{to}} di {{count}}", + "drawer": { + "tenantInline": "tenant {{id}}", + "serviceAccount": "account di servizio", + "stale": "inattivo 30g+", + "viewInLogs": "Vedi eventi nel Log Explorer", + "copySid": "Copia SID", + "copyUid": "Copia identità", + "copied": "Copiato", + "identity": "Identità", + "accountName": "Nome account", + "domain": "Dominio", + "hostname": "Hostname", + "sid": "SID", + "uidNumber": "UID", + "machineId": "ID macchina", + "tenant": "Tenant", + "adStatus": "Stato AD", + "enabled": "Abilitato", + "disabled": "Disabilitato", + "lifecycle": "Ciclo di vita", + "created": "Account creato", + "lastLogon": "Ultimo accesso", + "lastSeen": "Visto l’ultima volta nei log", + "deleted": "Account eliminato", + "noLifecycle": "Nessun evento del ciclo di vita registrato.", + "aliasGroup": "Gruppo identità", + "alias": { + "add": "Aggiungi gruppo identità", + "search": "Cerca gruppi…", + "none": "Nessun gruppo ancora", + "new": "Nuovo gruppo", + "unassign": "Rimuovi dal gruppo", + "unassigned": "Nessun gruppo", + "newPlaceholder": "Nome del nuovo gruppo (2–64 caratteri)", + "createAndAssign": "Crea e assegna", + "nameTooShort": "Il nome deve avere da 2 a 64 caratteri", + "updated": "Gruppo identità aggiornato", + "updateFailed": "Impossibile aggiornare il gruppo identità" + } + }, + "relative": { + "justNow": "proprio ora", + "minutesAgo": "{{count}}m fa", + "hoursAgo": "{{count}}h fa", + "daysAgo": "{{count}}g fa" + }, + "none": "—", + "allIdentities": "Tutti i gruppi identità", + "noneIdentity": "Nessun gruppo identità" + }, + "connectionKey": { + "title": "Chiave di connessione", + "subtitle1": "La chiave che gli agenti presentano quando si registrano su questa istanza.", + "subtitleEmphasis": "Viene usata solo per l'installazione degli agenti", + "subtitle2": "— non per i collector, le integrazioni o l'API. È gestita dall'agent-manager.", + "status": { + "label": "Stato", + "loading": "Caricamento…", + "unavailable": "Agent-manager non disponibile", + "active": "Attiva", + "unavailableHint": "Impossibile contattare l'agent-manager per leggere la chiave.", + "activeHint": "Gli agenti possono registrarsi con questa chiave." + }, + "token": { + "title": "Chiave di connessione", + "subtitle": "Tratta questo valore come una credenziale. Ruotarla emette una nuova chiave per le future installazioni degli agenti — gli agenti già registrati continuano a funzionare.", + "loadFailedTitle": "Impossibile caricare la chiave di connessione", + "unavailableTitle": "Chiave di connessione non disponibile", + "loadFailedHint": "La chiave è gestita dall'agent-manager, che non ha risposto. Riprova tra un momento.", + "retry": "Riprova", + "show": "Mostra chiave", + "hide": "Nascondi chiave", + "copy": "Copia", + "copied": "Copiato", + "regenerate": "Rigenera chiave di connessione", + "confirmTitle": "Rigenerare la chiave?", + "confirmBody": "Le nuove installazioni degli agenti avranno bisogno della nuova chiave. Gli agenti già registrati continuano a funzionare. Operazione irreversibile.", + "regenerating": "Rigenerazione…", + "confirmYes": "Sì, rigenera", + "cancel": "Annulla" + }, + "security": { + "title": "Raccomandazioni di sicurezza", + "subtitle": "Buone pratiche per proteggere questa credenziale.", + "rotateTitle": "Ruota ogni 90 giorni", + "rotateBody": "Pianifica una rotazione ricorrente. UTMStack può inviarti un promemoria via email quando la chiave ha più di 90 giorni.", + "rotateAction": "Configura promemoria", + "secretTitle": "Conservala come segreto", + "secretBody": "Non inserirla nel controllo di versione. Usa il tuo gestore di segreti (Vault, AWS SM, ecc.) e iniettala al momento dell'installazione.", + "auditTitle": "Verifica chi l'ha recuperata", + "auditBody": "Ogni recupero e rotazione è registrato nel log di audit dell'applicazione.", + "auditAction": "Vedi log di audit" + }, + "toast": { + "loadFailed": "Impossibile caricare la chiave di connessione", + "rotated": "Chiave di connessione ruotata", + "rotateFailed": "Impossibile ruotare la chiave di connessione", + "copyFailed": "Impossibile copiare" + } }, - "span": { - "recent": "intervallo recente", - "days_one": "ultimo {{count}} giorno", - "days_other": "ultimi {{count}} giorni", - "hours": "ultime {{n}} h" + "dataRetention": { + "title": "Conservazione dei dati", + "subtitle": "How long each dataset is kept, and when its records stop costing local disk.", + "loading": "Caricamento…", + "loadFailed": "Could not read the store.", + "retry": "Riprova", + "datasets": { + "logs": "Logs", + "alerts": "Alerts", + "statistics": "Ingestion statistics" + }, + "holding": "{{documents}} records · {{size}}", + "since": "since {{date}}", + "diskUsed": "Disk {{pct}}% used", + "keep": "Delete after", + "keepHint": "A record is deleted this many days after it happened, wherever it is stored by then.", + "cold": "Move to cold storage after", + "coldHint": "Older records move to object storage and stay queryable. 0 keeps everything on local disk.", + "coldUnavailable": "Set up cold storage below to move older records off local disk.", + "coldBeforeDelete": "Records have to move before they are deleted: use fewer days than the lifetime, or 0.", + "tieredNote": "This dataset moves records to cold storage. Going back to local-only needs the table rebuilt, so it cannot be turned off here.", + "days": "giorni", + "save": "Salva", + "saving": "Salvataggio…", + "toast": { + "saved": "Retention saved", + "noPermission": "You do not have permission to change retention", + "saveFailed": "Could not save the retention" + }, + "coldStorage": { + "title": "Cold storage", + "hint": "An object store the event store treats as a second, slower disk. Older records move there and are still queried from the same place — it is not an archive and nothing has to be restored.", + "active": "In use", + "inactive": "Not set up", + "writtenNotReady": "The bucket is configured but the store has not picked it up. Check that the deployment shares the store's configuration directory.", + "endpoint": "Bucket URL", + "accessKey": "Access key", + "secretKey": "Secret key", + "bucketLocked": "The credentials can be changed at any time. The bucket cannot, once records live in it: the parts already moved carry it.", + "enable": "Enable cold storage", + "update": "Update credentials", + "toast": { + "saved": "Cold storage configured", + "failed": "Could not configure cold storage" + }, + "kind": "Tipo", + "kind_s3": "Archivio oggetti compatibile S3", + "kind_local": "Cartella locale o NFS", + "kind_azure": "Azure Blob Storage", + "accountUrl": "URL dell'account di archiviazione", + "container": "Contenitore", + "accountName": "Nome account", + "accountKey": "Chiave account", + "useRole": "Usa il ruolo IAM del server invece delle chiavi", + "s3Hint": "Funziona con AWS S3 e qualsiasi archivio compatibile S3: MinIO, Ceph, Wasabi, Cloudflare R2 o Google Cloud Storage (endpoint https://storage.googleapis.com// con chiavi HMAC).", + "localHint": "I record passano alla cartella montata su /mnt/utmstack-cold nell'archivio eventi: una directory normale nella cartella dati, oppure una condivisione NFS montata sull'host su /clickhouse/cold prima dell'avvio dello stack. Nessuna credenziale richiesta.", + "changeWarning": "Records already moved to the current destination are not migrated. They stay there and stop being readable from here until the old destination is copied across by hand." + }, + "forbidden": { + "title": "Questa pagina è della piattaforma", + "body": "La conservazione riguarda le tabelle condivise da tutti i tenant: solo un amministratore della piattaforma può leggerla o modificarla." + } }, - "mitre": { - "title": "Principali tecniche MITRE ATT&CK", - "explore": "Esplora", - "empty": "Nessun avviso con tecnica assegnata" + "languageSettings": { + "title": "Lingua della piattaforma", + "subtitle": "Lingua predefinita per le schermate pre-login, le email di sistema e i nuovi utenti. Ogni utente può comunque scegliere la propria nel profilo.", + "label": "Lingua predefinita", + "hint": "Usata quando un utente non ha scelto la propria lingua.", + "save": "Salva", + "saving": "Salvataggio…", + "saved": "Lingua della piattaforma aggiornata", + "loadError": "Impossibile caricare l'impostazione della lingua", + "saveError": "Impossibile salvare l'impostazione della lingua" + }, + "branding": { + "title": "Brand", + "subtitle": "Personalizza UTMStack con l’identità della tua organizzazione — applicata ovunque: schermata di accesso, barra laterale, email e report.", + "enterpriseRequired": "Il white-label è una funzione Enterprise.", + "manageLicense": "Gestisci licenza", + "enable": { + "title": "White-label", + "description": "Sostituisci il marchio UTMStack con il tuo su tutta la piattaforma.", + "label": "Attiva il white-label" + }, + "identity": { + "title": "Identità", + "productName": "Nome del prodotto", + "productNameHint": "Mostrato nella barra del titolo, nella barra laterale e nelle email.", + "accent": "Colore d’accento", + "accentHint": "Colore primario per pulsanti, link e stati attivi.", + "custom": "Colore personalizzato" + }, + "logos": { + "title": "Loghi", + "hint": "PNG, SVG, WEBP, JPG o ICO. Fino a 5 MB.", + "logo": "Logo (chiaro)", + "logoDark": "Logo (scuro)", + "favicon": "Favicon" + }, + "reports": { + "title": "Risorse report", + "hint": "Incorporate nei report PDF generati.", + "reportLogo": "Logo report", + "reportCover": "Copertina report" + }, + "asset": { + "upload": "Carica", + "replace": "Sostituisci" + }, + "save": "Salva modifiche", + "saving": "Salvataggio…", + "saved": "Brand aggiornato", + "saveError": "Impossibile salvare il brand", + "uploaded": "Immagine caricata", + "uploadError": "Impossibile caricare l’immagine", + "loadError": "Impossibile caricare il brand", + "enterprise": { + "title": "Il white label è una funzione Enterprise", + "body": "Sostituisci il nome del prodotto, il logo e la copertina dei report con i tuoi, così il pannello e tutto ciò che genera portano il tuo marchio invece di quello di UTMStack.", + "upgrade": "Passa a Enterprise" + }, + "restore": "Ripristina i valori UTMStack", + "restored": "Marchio ripristinato ai valori UTMStack" + }, + "emailConfig": { + "title": "Configurazione email", + "subtitle": "Server SMTP usato per inviare notifiche di avvisi, report ed email dell’account.", + "server": { + "title": "Server SMTP", + "host": "Host", + "hostHint": "Nome host del tuo server SMTP.", + "port": "Porta", + "encryption": "Crittografia", + "username": "Nome utente", + "password": "Password", + "passwordSetHint": "È salvata una password. Lascia vuoto per mantenerla o digitane una nuova per cambiarla." + }, + "encryptionOpt": { + "TLS": "TLS", + "SSL": "SSL", + "NONE": "Nessuna" + }, + "sender": { + "title": "Mittente", + "from": "Indirizzo mittente", + "fromHint": "Indirizzo da cui vengono inviate le email.", + "organization": "Nome organizzazione", + "organizationHint": "Mostrato nelle email di notifica di avvisi e incidenti.", + "baseUrl": "URL base", + "baseUrlHint": "URL pubblico di questa istanza, usato per i link nelle email." + }, + "test": { + "button": "Invia test", + "sending": "Invio…", + "sentTo": "Verrà inviata un’email di prova a {{email}}.", + "success": "Email di prova inviata a {{email}}", + "fail": "Impossibile inviare l’email di prova", + "fromRequired": "Imposta un indirizzo mittente prima di testare" + }, + "save": "Salva modifiche", + "saving": "Salvataggio…", + "saved": "Configurazione email salvata", + "saveError": "Impossibile salvare la configurazione", + "loadError": "Impossibile caricare la configurazione", + "recipients": { + "alertsTitle": "Destinatari degli avvisi", + "incidentsTitle": "Destinatari degli incidenti", + "to": "A", + "cc": "CC", + "alertsHelper": "Indirizzi avvisati quando vengono generati nuovi avvisi. Se lasci il campo vuoto, gli avvisi non vengono inviati per email.", + "incidentsHelper": "Indirizzi avvisati alla creazione di un incidente. Se lasci il campo vuoto, gli incidenti non vengono inviati per email.", + "add": "Aggiungi" + } }, - "assets": { - "title": "Asset più presi di mira", - "viewAll": "Vedi tutto", - "asset": "Asset", - "alerts": "Avvisi", - "empty": "Nessun asset preso di mira negli avvisi recenti" + "dateFormat": { + "title": "Data e ora", + "subtitle": "Come vengono visualizzati i timestamp nella piattaforma. I log sono sempre archiviati in UTC.", + "timezone": { + "title": "Fuso orario", + "hint": "I timestamp vengono mostrati in questo fuso orario. I dati restano archiviati in UTC.", + "system": "Predefinito del browser", + "now": "Ora: {{value}}" + }, + "format": { + "title": "Formato data", + "hint": "Stile usato per date e orari." + }, + "styles": { + "short": "Breve", + "medium": "Medio", + "long": "Lungo", + "full": "Completo" + }, + "save": "Salva modifiche", + "saving": "Salvataggio…", + "saved": "Impostazioni data salvate", + "saveError": "Impossibile salvare le impostazioni", + "loadError": "Impossibile caricare le impostazioni" + }, + "about": { + "title": "Informazioni su questa istanza", + "subtitle": "Versione, licenza e stato del sistema di questo deployment UTMStack.", + "loading": "Caricamento delle informazioni dell'istanza…", + "edition": { + "enterprise": "Enterprise", + "community": "Community" + }, + "fields": { + "hostname": "Server", + "instanceId": "ID istanza", + "noInstanceMeta": "Nessun metadato dell'istanza disponibile." + }, + "license": { + "title": "Licenza", + "enterpriseMssp": "Enterprise · MSSP", + "datasources": "Datasources", + "communityLimited": "Limite Community", + "unlimited": "Illimitato", + "expires": "Scade", + "managedNote": "Edizione, limiti dei datasources e caricamento licenza si gestiscono nella pagina Licenza.", + "view": "Vedi licenza", + "ingest": "Volume di ingest", + "notMetered": "Non misurato", + "gbPerMonth": "{{gb}} GB/mese" + }, + "services": { + "backend": { + "name": "Backend API", + "desc": "Gateway REST, autenticazione e orchestrazione dei moduli." + }, + "opensearch": { + "name": "OpenSearch", + "desc": "Archiviazione di log ed eventi.", + "detail": "{{nodes}} nodi · {{shards}} shard" + }, + "unreachable": "Irraggiungibile" + }, + "status": { + "up": "Integro", + "degraded": "Degradato", + "down": "Non attivo", + "unknown": "Sconosciuto" + }, + "health": { + "title": "Stato del sistema", + "allHealthy": "Tutti i servizi integri. Aggiorna per ricontrollare.", + "issues_one": "{{count}} servizio richiede attenzione.", + "issues_other": "{{count}} servizi richiedono attenzione.", + "refresh": "Aggiorna" + }, + "usage": { + "title": "Origini dati", + "subtitle": "Origini dati configurate in questa installazione.", + "ofUnlimited": "di illimitato", + "ofLimit": "di {{limit}}", + "overLimit": "Oltre il limite della licenza — i dati oltre il limite sono a rischio.", + "configured": "configurate" + }, + "support": { + "title": "Supporto", + "docs": "Documentazione", + "repo": "Repository GitHub", + "issues": "Segnala un problema", + "website": "utmstack.com" + }, + "legal": { + "title": "Note legali", + "license": "Licenza", + "security": "Divulgazione di sicurezza", + "copyright": "© {{year}} UTMStack. Tutti i diritti riservati." + } }, - "compliance": { - "title": "Punteggio di conformità", - "reports": "Report", - "empty": "Nessun report di conformità ancora generato" + "logExplorer": { + "title": "Esploratore di log", + "eventsIn": "eventi in", + "searching": "Ricerca…", + "query": { + "allDataTypes": "Tutti i tipi di dato", + "dataTypes": "Tipi di dato", + "exportCsv": "Esporta CSV", + "filterDataTypes": "Filtra tipi di dato…", + "noDataTypes": "Nessun tipo di dato", + "noDataTypesMatch": "Nessun tipo di dato corrispondente", + "noTextSearch": "Questa origine non ha un campo full-text — filtra per campo", + "refresh": "Aggiorna", + "run": "Esegui", + "search": "Cerca", + "searchPlaceholder": "Cerca in tutti i campi…" + }, + "time": { + "15m": "Ultimi 15 minuti", + "1h": "Ultima ora", + "6h": "Ultime 6 ore", + "24h": "Ultime 24 ore", + "7d": "Ultimi 7 giorni", + "30d": "Ultimi 30 giorni" + }, + "ops": { + "is": "è", + "isNot": "non è", + "contains": "contiene", + "exists": "esiste", + "between": "tra", + "search": "cerca", + "isOneOf": "è uno di", + "isNotOneOf": "non è nessuno di", + "doesNotContain": "no contiene", + "startsWith": "empieza con", + "doesNotStartWith": "no empieza con", + "endsWith": "termina con", + "doesNotEndWith": "no termina con", + "doesNotExist": "no existe", + "notBetween": "no está entre", + "greaterThan": "es mayor que", + "greaterThanOrEquals": "es mayor o igual que", + "lessThan": "es menor que", + "lessThanOrEquals": "es menor o igual que" + }, + "filters": { + "label": "Filtri", + "clearAll": "Cancella tutto" + }, + "fields": { + "title": "Campi", + "filterPlaceholder": "Filtra campi…", + "none": "Nessun campo", + "selected": "Campi selezionati", + "available": "Campi disponibili", + "topValues_one": "Top {{count}} valore", + "topValues_other": "Top {{count}} valori", + "loading": "Caricamento…", + "noValues": "Nessun valore", + "addColumn": "Aggiungi come colonna", + "removeColumn": "Rimuovi colonna dalla tabella", + "filterFor": "Filtra per il valore", + "filterOut": "Escludi il valore", + "empty": "(vuoto)" + }, + "results": { + "dataTypesFailed": "Impossibile caricare i tipi di dato.", + "endOfResults": "{{count}} eventi caricati", + "loadingMore": "Caricamento in corso…", + "message": "Messaggio", + "none": "Nessun log corrisponde a questa query.", + "removeColumn": "Rimuovi {{field}}", + "retry": "Riprova", + "searchFailed": "Ricerca fallita.", + "searching": "Ricerca…", + "source": "Origine", + "time": "Ora", + "scope": "Cercato in {{dataset}} · {{dataType}}.", + "searchAllDataTypes": "Cerca in tutti i tipi" + }, + "detail": { + "fieldsCount_one": "{{count}} campo", + "fieldsCount_other": "{{count}} campi", + "copyJson": "Copia JSON", + "copied": "Documento copiato", + "parsedFields": "Campi analizzati", + "json": "JSON", + "filterFor": "Filtra per", + "filterOut": "Escludi", + "surrounding": "Eventi circostanti", + "surroundingHint": "Mostra gli eventi ±15 min attorno a questo, dalla stessa sorgente" + }, + "view": { + "table": "Tabella", + "chart": "Grafico" + }, + "chart": { + "aggregateOn": "Aggrega su", + "per": "per", + "topValues": "— top 20 valori", + "building": "Creazione grafico…", + "failed": "Impossibile creare il grafico per questo campo.", + "noData": "Nessun dato da graficare." + }, + "intervals": { + "minute": "Minuto", + "hour": "Ora", + "day": "Giorno", + "week": "Settimana", + "month": "Mese", + "quarter": "Trimestre", + "year": "Anno" + }, + "toast": { + "exportFailed": "Esportazione fallita" + }, + "builder": { + "add": "Aggiungi filtro", + "filterValues": "Filtra valori…", + "loadingValues": "Caricamento valori…", + "noValues": "Nessun valore.", + "cancel": "Annulla", + "confirm": "Aggiungi", + "pickValue": "Pick a value to add the filter." + }, + "related": { + "nLogs_one": "{{count}} log", + "nLogs_other": "{{count}} log", + "truncated": "Mostrando i primi {{count}} log correlati (insieme completo più grande)." + }, + "saved": { + "title": "Salvati", + "empty": "Nessuna ricerca salvata", + "saveCurrent": "Salva ricerca corrente", + "save": "Salva", + "namePlaceholder": "Nome ricerca", + "delete": "Elimina", + "saved": "Salvata “{{name}}”", + "loading": "Caricamento…", + "loadFailed": "Impossibile caricare le ricerche salvate", + "saveFailed": "Impossibile salvare la ricerca", + "deleteFailed": "Impossibile eliminare la ricerca", + "unreadable": "Impossibile leggere quella ricerca salvata" + } }, - "health": { - "title": "Stato del sistema", - "details": "Dettagli", - "services": { - "backend": "API backend", - "opensearch": "Cluster OpenSearch", - "socai": "Motore SOC-AI" - }, - "detail": { - "noClusterInfo": "nessuna informazione sul cluster", - "disabled": "disabilitato", - "tools": "{{n}} strumenti", - "unreachable": "irraggiungibile", - "pending": "…" - } - } - }, - "nav": { - "home": "Home", - "dashboards": "Dashboard", - "dashboardList": "Elenco dashboard", - "visualizationList": "Widget", - "newDashboard": "Nuova dashboard", - "newVisualization": "Nuovo widget", - "threatManagement": "Gestione minacce", - "alerts": "Avvisi", - "incidents": "Incidenti", - "adversaryView": "Vista avversari", - "soar": "SOAR", - "flows": "Flussi", - "executionHistory": "Cronologia esecuzioni", - "interactiveConsole": "Console interattiva", - "logExplorer": "Esplora log", - "userAuditor": "Auditor utenti", - "threatIntelligence": "Intelligence sulle minacce", - "threat-intel": { - "indicators": "Indicatori", - "analyzt": "Analista IA", - "triage": "Triage", - "report": "Report" + "integrations": { + "title": "Integrazioni", + "searchPlaceholder": "Cerca integrazioni…", + "noMatch": "Nessuna integrazione corrisponde.", + "browseMarketplace": "Sfoglia marketplace", + "loading": "Caricamento integrazioni…", + "addCustom": { + "title": "Aggiungi integrazione personalizzata", + "description": "Crea una nuova fonte personalizzata", + "cta": "Crea" + }, + "tabs": { + "all": "Tutte", + "agents": "Agenti", + "collectors": "Collector", + "cloud": "Cloud", + "custom": "Personalizzata" + }, + "kind": { + "agents & syslog": "Agente", + "device": "Collector", + "antivirus": "Collector", + "other": "Collector", + "custom": "Personalizzata", + "cloud": "Cloud", + "utmstack modules": "Collector" + }, + "status": { + "configured": "Configurata", + "available": "Disponibile" + }, + "card": { + "manage": "Gestisci →", + "setup": "Configura →", + "eventsPerSec": "{{rate}} e/s", + "enabled": "Attivato", + "setupShort": "Configura" + }, + "drawer": { + "manage": "Gestisci", + "openDashboard": "Apri dashboard", + "viewEvents": "Visualizza eventi", + "documentation": "Documentazione", + "getInstallCmd": "Ottieni comando di installazione", + "setupCollector": "Configura collector", + "connect": "Connetti", + "configureCustom": "Configura fonte personalizzata", + "eventsRate": "{{rate}} eventi/s · {{count}} in 24h", + "manageRules": "Regole", + "manageFilters": "Filtri" + }, + "setup": { + "agent": { + "howItWorksTitle": "Come funziona", + "howItWorksBody": "L'agente {{name}} è un piccolo daemon che viene eseguito sull'host e inoltra gli eventi locali a UTMStack su una connessione TLS autenticata. Si aggiorna automaticamente e segnala il suo stato di salute.", + "installTitle": "Installa su {{name}}", + "installHint": "Esegui questo comando su ogni host {{name}} che desideri monitorare. Il token codifica già il tuo workspace attuale.", + "afterTitle": "Cosa vedrai dopo l'installazione", + "after1": "L'host appare sotto Origini dati entro ~60 secondi dall'avvio dell'agente.", + "after2": "La telemetria inizia a fluire in Log Explorer, limitata al tuo workspace.", + "after3": "L'agente auto-segnala lo stato di CPU/memoria/disco a UTMStack.", + "actionLabel": "Azione", + "platformLabel": "Piattaforma", + "optionsLabel": "Opzioni", + "skipCertValidation": "Salta la convalida del certificato TLS (server autofirmato)", + "noRemoteControl": "Disabilita l'esecuzione remota di comandi su questo host", + "loadingToken": "Caricamento token…", + "actions": { + "install": "Installa", + "uninstall": "Disinstalla" + }, + "prereqTitle": "Requisiti pre-installazione", + "prereqBody": "L'agente UTMStack comunica con il server tramite le seguenti porte. Assicurarsi che siano aperte tra l'host e UTMStack prima di procedere con l'installazione:", + "sensitiveWarning": "Il comando seguente contiene un token di registrazione sensibile — non condividerlo.", + "uninstall": { + "title": "Disinstalla l'agente", + "body": "Eseguire questo comando sull'host per arrestare e rimuovere l'agente UTMStack e i relativi servizi. Utilizza la piattaforma selezionata in precedenza." + }, + "macCompat": "Richiede macOS 11 (Big Sur) o versione successiva su Apple Silicon (M1/M2/M3 o più recente). I Mac basati su Intel non sono supportati." + }, + "collector": { + "howItWorksTitle": "Come funziona", + "howItWorksBody": "{{name}} non esegue un agente UTMStack. Invece, installi il collector UTMStack da qualche parte sulla rete che sia il tuo dispositivo {{name}} che UTMStack possono raggiungere. {{name}} invia syslog al collector, il collector analizza, normalizza e inoltra gli eventi a UTMStack.", + "step1Title": "1 · Installa il collector UTMStack", + "step1Hint": "Esegui su un host Linux con accesso di rete dal dispositivo {{name}}.", + "step2Title": "2 · Configura {{name}} per inviare syslog", + "step2Hint": "Sul dispositivo {{name}}, punta l'inoltro syslog all'indirizzo del collector su {{port}}.", + "vendorDocs": "Vedi istruzioni specifiche del fornitore", + "step3Title": "3 · Verifica", + "step3Body": "Entro pochi minuti dovresti vedere gli eventi di {{name}} sotto source: {{source}} in Log Explorer e una nuova voce in Origini dati.", + "endpoint": { + "title": "Dettagli di connessione", + "hint": "Configurare {{name}} per inoltrare i log al Collector utilizzando l'host e la porta indicati di seguito." + }, + "syslog": { + "sections": { + "sendLogs": { + "title": "1 · Invia log a UTMStack", + "body": "Configurare il dispositivo per inviare messaggi syslog tramite UDP (514) o TCP (514) all'agente UTMStack." + }, + "enableCollector": { + "title": "2 · Abilita il collector syslog", + "body": "Abilitare il log collector e l'integrazione syslog nel file di configurazione in cui è installato l'agente UTMStack." + }, + "activate": { + "title": "3 · Attiva", + "body": "Attivare il modulo UTMStack affinché gli eventi inizino a fluire nel Log Explorer." + } + } + }, + "netflow": { + "source": "Dispositivo di rete", + "step1": { + "title": "Abilita il listener NetFlow sul Collector", + "body": "Sull'host in cui è installato il Collector, eseguire questo comando per aprire il collector NetFlow sulla porta 2055:", + "note": "NetFlow utilizza solo UDP — TCP e TLS non sono supportati per questo protocollo." + }, + "step2": { + "title": "Configura il dispositivo per esportare NetFlow", + "body": "Puntare l'esportazione NetFlow del router o firewall verso l'host Collector sulla porta {{port}} UDP. L'esempio seguente è per Cisco IOS — consultare la documentazione del fornitore per altre piattaforme:", + "note": "Sostituire con il nome dell'interfaccia su cui monitorare il traffico (es. GigabitEthernet0/0). Applicare ingress/egress su ogni interfaccia pertinente." + } + }, + "cisco": { + "source": "Cisco ASA", + "step1": { + "title": "Abilita il listener Cisco ASA sul Collector", + "body": "Sull'host in cui è installato il Collector, eseguire questo comando per aprire il listener di log Cisco ASA:", + "note": "Per utilizzare TCP al posto di UDP, sostituire udp con tcp nel comando precedente." + }, + "step2": { + "title": "Configura Cisco ASA per l'inoltro dei log", + "body": "Sul Cisco ASA, abilitare syslog e puntarlo verso l'host Collector sulla porta {{port}}. Eseguire questi comandi in modalità EXEC privilegiata (sostituire con il nome dell'interfaccia interna o di gestione):" + } + }, + "ciscoSwitch": { + "source": "Cisco Switch", + "step1": { + "title": "Abilita il listener Cisco Switch sul Collector", + "body": "Sull'host in cui è installato il Collector, eseguire questo comando per aprire il listener di log Cisco Switch:", + "note": "Per utilizzare TCP al posto di UDP, sostituire udp con tcp nel comando precedente." + }, + "step2": { + "title": "Configura lo switch per l'inoltro dei log", + "body": "In modalità EXEC privilegiata sul Cisco switch, abilitare syslog e puntarlo verso l'host Collector sulla porta {{port}}:" + } + }, + "ciscoMeraki": { + "source": "Cisco Meraki", + "step1": { + "title": "Abilita il listener Cisco Meraki sul Collector", + "body": "Sull'host in cui è installato il Collector, eseguire questo comando per aprire il listener di log Cisco Meraki:", + "note": "Per utilizzare TCP al posto di UDP, sostituire udp con tcp nel comando precedente." + }, + "step2": { + "title": "Configura Meraki per l'inoltro dei log", + "body": "Nel Meraki Dashboard, andare su Network-wide → Configure → General, scorrere fino alla sezione Reporting e aggiungere un server syslog con l'IP del Collector e la porta {{port}}. Selezionare tutti i ruoli che si desidera inoltrare." + } + }, + "ciscoFirepower": { + "source": "Cisco Firepower", + "step1": { + "title": "Abilita il listener Cisco Firepower sul Collector", + "body": "Sull'host in cui è installato il Collector, eseguire questo comando per aprire il listener di log Cisco Firepower:", + "note": "Per utilizzare TCP al posto di UDP, sostituire udp con tcp nel comando precedente." + }, + "step2": { + "title": "Configura Firepower per l'inoltro dei log", + "body": "In Firepower Management Center (FMC), andare su Devices → Platform Settings, modificare o creare un criterio e navigare fino a Syslog → Syslog Servers. Aggiungere l'IP del Collector con la porta {{port}} (UDP), quindi assegnare il criterio ai dispositivi e distribuire." + } + }, + "vmware": { + "source": "VMware ESXi", + "step1": { + "title": "Abilita il listener VMware sul Collector", + "body": "Sull'host in cui è installato il Collector, eseguire questo comando per aprire il listener syslog VMware ESXi. ESXi trasmette tramite TCP:", + "note": "Per un canale cifrato, utilizzare tls al posto di tcp (caricare prima i certificati sul Collector)." + }, + "step2": { + "title": "Punta il syslog ESXi verso il Collector", + "body": "Aprire una sessione SSH/ESXi Shell sull'host (o usare il vSphere Client: Host → Configure → Advanced System Settings → Syslog.global.logHost). Impostare il loghost remoto su {{host}}:{{port}} e ricaricare la configurazione:", + "note": "Su vSphere è possibile impostare Syslog.global.logHost sullo stesso valore tcp://host:port invece di eseguire esxcli." + }, + "step3": { + "title": "Apri il firewall ESXi per syslog", + "body": "Consentire il syslog in uscita attraverso il firewall ESXi in modo che l'host possa raggiungere il Collector:" + } + }, + "as400": { + "intro": { + "title": "Come funziona", + "body": "L'AS/400 Collector è un servizio Linux che si connette direttamente ai sistemi AS/400 (IBM i) e recupera le voci del registro di sicurezza, trasmettendole in modo sicuro a UTMStack per la correlazione e gli avvisi.", + "note": "Nulla viene installato sull'AS/400 stesso — il Collector viene eseguito su un host Linux con accesso di rete ai sistemi AS/400.", + "diagram": { + "source": "i tuoi journal", + "edge1": "journal", + "collector": "AS/400 Collector", + "collectorSub": "recupera dall'AS/400", + "edge2": "sicuro", + "utmstackSub": "avvisi & correlazione" + } + }, + "install": { + "title": "Installa l'AS/400 Collector", + "body": "Eseguire questo comando su un host Linux che possa raggiungere sia UTMStack che i sistemi AS/400 tramite la rete.", + "reuse": "Hai già installato l'AS/400 Collector? Salta questo passaggio — aggiungi semplicemente i tuoi server al file di configurazione nel passaggio successivo." + }, + "configure": { + "title": "Aggiungi i tuoi server AS/400", + "body": "Modificare as400-config.yaml nella directory di installazione del collector e aggiungere ogni sistema AS/400 che si desidera monitorare:", + "note": "È possibile elencare più server. Il collector monitora questo file e si ricarica automaticamente al salvataggio — non è necessario riavviarlo." + }, + "journal": { + "title": "Abilita il journaling di audit sull'AS/400", + "body": "Su ogni sistema AS/400, assicurarsi che il journal di audit QAUDJRN sia attivo. Fare riferimento alla documentazione IBM per i passaggi esatti — la procedura varia tra le versioni di IBM i." + }, + "uninstall": { + "title": "Opzionale — Disinstalla il Collector", + "body": "Eseguire questo comando sull'host in cui è installato l'AS/400 Collector per arrestare il servizio e rimuovere tutti i file." + } + }, + "bitdefender": { + "intro": { + "title": "Come funziona", + "body": "UTMStack si connette a Bitdefender GravityZone utilizzando la chiave API per configurare l'Event Push Service. GravityZone invia quindi eventi di sicurezza direttamente a UTMStack per la correlazione e gli avvisi.", + "diagram": { + "source": "eventi endpoint", + "edge": "Event Push Service", + "utmstackSub": "avvisi & correlazione" + }, + "note": "Nessun agente viene installato su GravityZone — UTMStack si registra come destinazione push utilizzando credenziali API di sola lettura." + }, + "whitelist": { + "title": "Aggiungi alla whitelist gli IP di Bitdefender", + "body": "I seguenti indirizzi IP di Bitdefender GravityZone devono essere consentiti attraverso il firewall sulla porta 8000 affinché l'Event Push Service possa raggiungere UTMStack:", + "note": "Aggiungere questi IP al firewall o al gruppo di sicurezza prima di completare la configurazione." + }, + "apiSection": "Ottieni le credenziali API", + "api": { + "myAccount": { + "title": "Apri Il Mio Account", + "body": "Nella console Bitdefender GravityZone, fare clic su My Account." + }, + "accessUrl": { + "title": "Annota l'URL di accesso", + "body": "Scorrere fino alla sezione Control Center API e salvare l'Access URL — verrà inserito nel modulo delle credenziali di seguito. Quindi aprire la sezione della chiave API e fare clic su Add in cima alla tabella." + }, + "createKey": { + "title": "Crea una chiave API", + "body": "Scrivere una descrizione per la chiave API, selezionare l'opzione Event Push Service API e fare clic su Save. Copiare la chiave generata." + } + }, + "companySection": "Ottieni gli ID azienda", + "company": { + "myCompany": { + "title": "Apri La Mia Azienda", + "body": "Nella console GravityZone, fare clic su My Company." + }, + "licensing": { + "title": "Annota gli ID azienda", + "body": "Aprire la sezione Licensing e salvare gli ID azienda che si desidera monitorare — inserirli separati da virgola nel modulo delle credenziali di seguito." + } + }, + "credentials": { + "title": "Inserisci le credenziali", + "body": "Inserire l'Access URL, la chiave API, l'IP pubblico di UTMStack (dove GravityZone invierà gli eventi) e gli ID aziendali da monitorare. UTMStack verifica le credenziali prima del salvataggio." + }, + "fields": { + "accessUrl": { + "label": "URL di accesso GravityZone" + }, + "connectionKey": { + "label": "Chiave API" + }, + "utmPublicIP": { + "label": "IP pubblico UTMStack" + }, + "companyIds": { + "label": "ID aziendali (separati da virgola)" + } + } + }, + "eset": { + "source": "ESET Protect", + "step1": { + "title": "Abilitare il listener ESET sul Collector", + "body": "Sull'host in cui è installato il Collector, eseguire questo comando per aprire il listener syslog di ESET:", + "note": "Per utilizzare TCP invece di UDP, sostituire udp con tcp nel comando precedente." + }, + "console": { + "moreMenu": { + "title": "Aprire il menu More", + "body": "Nella barra laterale della console ESET Protect, fare clic sul menu More." + }, + "serverConfig": { + "title": "Aprire Server settings", + "body": "Nella sezione More, aprire la sezione Server settings (configurazione del server)." + }, + "advanced": { + "title": "Espandere Advanced settings", + "body": "Fare clic su Advanced settings per espandere l'elenco completo delle opzioni di configurazione." + }, + "syslog": { + "title": "Configurare il server Syslog", + "body": "Scorrere fino a Syslog server, abilitare Export logs to Syslog e impostare la destinazione sull'host Collector sulla porta {{port}} (UDP). ESET invia LEEF/syslog, che il Collector acquisisce come tipo di dati antivirus-esmc-eset." + } + } + }, + "kaspersky": { + "source": "Kaspersky Security", + "step1": { + "title": "Abilitare il listener Kaspersky sul Collector", + "body": "Sull'host in cui è installato il Collector, eseguire questo comando per aprire il listener syslog di Kaspersky:", + "note": "Per utilizzare TCP invece di UDP, sostituire udp con tcp nel comando precedente." + }, + "console": { + "consoleSettings": { + "title": "Aprire Console settings → Integration", + "body": "Nella barra laterale di Kaspersky Security Center, aprire Console settings e fare clic sul sottomenu Integration." + }, + "siem": { + "title": "Aprire le impostazioni di integrazione SIEM", + "body": "Nella sezione Integration, selezionare SIEM e fare clic sul collegamento Settings per aprire la configurazione di esportazione." + }, + "configure": { + "title": "Configurare l'esportazione SIEM", + "body": "Abilitare l'esportazione e configurare Kaspersky per inviare gli eventi in formato Splunk (CEF) all'host Collector sulla porta {{port}} (UDP). Il Collector li acquisisce come tipo di dati antivirus-kaspersky." + } + } + }, + "sophos": { + "intro": { + "title": "Sophos Central — API Plugin", + "body": "Sophos Central fornisce API sicure per recuperare dati di eventi e avvisi. UTMStack si connette a queste API per centralizzare il monitoraggio e migliorare la visibilità della sicurezza — nessun agente o collector richiesto.", + "diagram": { + "source": "Sophos Central API", + "edge": "HTTPS API", + "utmstackSub": "Acquisisce e correla" + }, + "note": "UTMStack interroga periodicamente la Sophos Central API. Assicurarsi che le credenziali API create in seguito dispongano di accesso in lettura a eventi e avvisi." + }, + "apiSection": "Generare le credenziali API in Sophos Central", + "steps": { + "apiCredentials": { + "title": "Aprire API Credentials Management", + "body": "In Sophos Central Admin, navigare fino a Global Settings → API Credentials Management." + }, + "addCredential": { + "title": "Creare una nuova credenziale", + "body": "Fare clic su Add Credential. Inserire un Name e una Description, selezionare il Role appropriato, quindi fare clic su Add." + }, + "copyIds": { + "title": "Copiare Client ID e Client Secret", + "body": "Copiare il Client ID e il Client Secret e conservarli in modo sicuro.", + "secretNote": "Il Client Secret viene visualizzato una sola volta. Salvarlo in un luogo sicuro prima di chiudere questa finestra." + } + }, + "credentialsSection": "Connetti a UTMStack", + "credentials": { + "title": "Aggiungere le credenziali Sophos Central", + "body": "Inserire le credenziali appena create. È possibile aggiungere più di un account Sophos facendo clic su Aggiungi gruppo di configurazione." + }, + "fields": { + "clientId": { + "label": "Client ID" + }, + "apiKey": { + "label": "Client Secret / Chiave API" + } + } + }, + "webroot": { + "sections": { + "login": { + "title": "1 · Accedere alla console di gestione", + "body": "Accedere alla console di gestione Webroot. Si apre nella scheda Sites." + }, + "openSettings": { + "title": "2 · Aprire Settings", + "body": "Fare clic sulla scheda Settings." + }, + "apiAccess": { + "title": "3 · Aprire API Access", + "body": "Dalla scheda Subscriptions, fare clic sulla scheda API Access." + }, + "createCredential": { + "title": "4 · Creare una credenziale client", + "body": "Fare clic su New e compilare Name e Description. Leggere il contratto SecureAnywhere Business Solution e Unity API, quindi fare clic su Create." + }, + "noteClientSecret": { + "title": "5 · Copiare il client ID e il segreto", + "body": "Salvare il Client ID dall'elenco e il Client Secret visualizzato una sola volta. Fare clic su \"I have made note of the client secret\" per confermare." + }, + "fillForm": { + "title": "6 · Compilare il modulo", + "body": "Fornire il client ID e il client secret a UTMStack. Se necessario, è possibile aggiungere più gruppi di configurazione Webroot." + }, + "activate": { + "title": "7 · Attivare", + "body": "Attivare il modulo UTMStack affinché gli eventi Webroot inizino a fluire." + } + } + }, + "sentinelOne": { + "source": "SentinelOne", + "step1": { + "title": "Abilitare il listener SentinelOne sul Collector", + "body": "Sull'host in cui è installato il Collector, eseguire questo comando per aprire il listener syslog di SentinelOne. SentinelOne trasmette CEF via TCP:", + "note": "Per un canale crittografato, utilizzare tls invece di tcp (caricare prima i certificati sul Collector)." + }, + "console": { + "settings": { + "title": "Aprire le impostazioni di SentinelOne", + "body": "Nella barra laterale della console di gestione di SentinelOne, fare clic sul menu Settings." + }, + "syslog": { + "title": "Configurare l'integrazione Syslog", + "body": "Andare su Integrations → Syslog e abilitarlo. Impostare l'host su {{host}} e la porta su {{port}}, mantenere il formato come CEF, fare clic su Test per verificare la connessione, quindi su Save." + } + } + }, + "office365": { + "intro": { + "title": "Come funziona", + "body": "UTMStack si connette a Microsoft 365 tramite un'app Azure AD registrata e interroga periodicamente l'Office 365 Management Activity API per eventi di audit e sicurezza. Nessun agente viene installato nel tenant.", + "diagram": { + "source": "eventi di audit e sicurezza", + "edge": "Management API", + "utmstackSub": "correlazione e avvisi" + }, + "note": "UTMStack richiede accesso API in sola lettura — non vengono richieste autorizzazioni di scrittura." + }, + "appSection": "Registrazione dell'app Azure", + "steps": { + "azurePortal": { + "title": "Aprire Microsoft Entra ID", + "body": "Aprire il Azure Portal (portal.azure.com) e fare clic su Microsoft Entra ID." + }, + "appRegistrations": { + "title": "Andare in App registrations", + "body": "Nel menu a sinistra, fare clic su App registrations." + }, + "registerApp": { + "title": "Registrare una nuova app", + "body": "Fare clic su New registration. Denominarlo UTMStack O365 Agent, selezionare Accounts in this organizational directory only (Single-tenant) e fare clic su Register." + }, + "clientSecret": { + "title": "Creare un client secret", + "body": "Andare su Certificates & Secrets → New client secret. Aggiungere una descrizione, impostare la scadenza su 730 days (24 months) e fare clic su Add.", + "copyNote": "Copiare immediatamente il valore del segreto — viene visualizzato una sola volta e non può essere recuperato in seguito." + }, + "apiPermissions": { + "title": "Aggiungere le autorizzazioni per l'Office 365 Management API", + "body": "Andare su API Permissions → Add a permission e cercare Office 365 Management APIs." + }, + "activityFeed": { + "title": "Concedere le autorizzazioni ActivityFeed", + "body": "Selezionare Application Permissions e aggiungere ActivityFeed.Read e ActivityFeed.ReadDlp. Fare clic su Grant admin consent e confermare." + }, + "graphPermissions": { + "title": "Aggiungere le autorizzazioni Microsoft Graph", + "body": "Tornando su Add a permission, fare clic su Microsoft Graph." + }, + "delegatedPermissions": { + "title": "Aggiungere le autorizzazioni delegate SecurityAlert", + "body": "Selezionare Delegated Permissions e aggiungere SecurityAlert.Read.All e SecurityAlert.ReadWrite.All. Fare clic su Grant admin consent e confermare." + }, + "appPermissions": { + "title": "Aggiungere le autorizzazioni applicazione SecurityAlert", + "body": "Selezionare Application Permissions e aggiungere SecurityAlert.Read.All e SecurityAlert.ReadWrite.All. Fare clic su Grant admin consent e confermare." + }, + "noteIds": { + "title": "Copiare gli ID dell'app", + "body": "Andare nella sezione Overview dell'app e copiare l'Application (client) ID e il Directory (tenant) ID. È necessario anche il valore segreto copiato al passaggio 4." + } + }, + "credentialsSection": "Credenziali", + "credentials": { + "title": "Connettere il tenant Microsoft 365", + "body": "Inserire i dettagli dei passaggi precedenti. UTMStack verifica le credenziali prima del salvataggio. È possibile aggiungere più gruppi di configurazione." + }, + "fields": { + "tenantId": { + "label": "Tenant ID (Directory ID)" + }, + "clientId": { + "label": "Client ID (Application ID)" + }, + "clientSecret": { + "label": "Client Secret" + }, + "cloudEnv": { + "label": "Ambiente cloud (facoltativo)", + "hint": "Commercial (default), GCC, GCCHigh, or DoD" + } + } + }, + "github": { + "source": "GitHub", + "step1": { + "title": "Abilita il listener webhook di GitHub sul Collector", + "body": "Sull'host in cui è installato il Collector, esegui questo comando per aprire il listener webhook HTTPS per GitHub:", + "tokenNote": "Il terminale stamperà un token segreto — copialo immediatamente. Non verrà mostrato di nuovo." + }, + "certWarning": { + "title": "GitHub richiede un certificato TLS firmato da una CA", + "body": "GitHub recapita i webhook solo agli endpoint HTTPS con un certificato emesso da una CA pubblica (i certificati autofirmati vengono rifiutati). Assicurati che l'host Collector disponga di un certificato di dominio valido prima di registrare il webhook." + }, + "step2": { + "title": "Registra il webhook in GitHub", + "body": "Nel tuo repository o nella tua organizzazione, vai su Settings → Webhooks → Add webhook e compila il modulo:", + "payloadUrl": "URL del payload", + "contentType": "Tipo di contenuto", + "secret": "Segreto", + "secretHint": "Incolla il token stampato dal Collector nel passaggio precedente.", + "events": "Quali eventi", + "eventsHint": "Invia tutto — oppure seleziona tipi di evento specifici." + } + }, + "salesforce": { + "sections": { + "openSetup": { + "title": "1 · Apri Setup", + "body": "Vai a Setup e seleziona \"Setup for the current app\" in alto a destra dello schermo." + }, + "appManager": { + "title": "2 · Apri App Manager", + "body": "Digita \"App Manager\" nella casella di ricerca rapida e seleziona App Manager." + }, + "newConnectedApp": { + "title": "3 · Crea una nuova Connected App", + "body": "Nella schermata Lightning Experience App Manager, fai clic su \"New Connected App\" e compila i campi." + }, + "oauthSettings": { + "title": "4 · Abilita le impostazioni OAuth", + "body": "Nella sezione \"API (Enable OAuth Settings)\", spunta \"Enable OAuth Settings\" e usa https://login.salesforce.com/services/oauth2/success come Callback URL." + }, + "oauthScopes": { + "title": "5 · Aggiungi gli scope OAuth", + "body": "Seleziona \"Access Connect REST API resources (chatter_api)\" sotto Selected OAuth Scopes." + }, + "save": { + "title": "6 · Salva", + "body": "Salva le modifiche e seleziona Continue nella schermata successiva." + }, + "manageConsumer": { + "title": "7 · Apri Manage Consumer Details", + "body": "All'interno della tua Connected App, vai su \"API (Enable OAuth Settings)\" e fai clic su \"Manage Consumer Details\" accanto a Consumer Key e Secret." + }, + "copyCredentials": { + "title": "8 · Copia la consumer key e il secret", + "body": "Verifica la tua identità. Consumer Key e Consumer Secret compaiono sotto \"Consumer Details\". Copiali entrambi con il pulsante Copy." + }, + "fillForm": { + "title": "9 · Compila il modulo", + "body": "Fornisci a UTMStack la Consumer Key, il Consumer Secret, il nome utente e la password Salesforce." + }, + "activate": { + "title": "10 · Attiva", + "body": "Attiva il modulo UTMStack per avviare il flusso degli eventi Salesforce." + } + } + }, + "iis": { + "sections": { + "enableModule": { + "title": "1 · Abilita il modulo IIS Filebeat", + "body": "Sull'host dell'agente UTMStack, esegui:\ncd \"C:\\Program Files\\UTMStack\\UTMStack Agent\\beats\\filebeat\\\" && filebeat modules enable iis" + }, + "configureModule": { + "title": "2 · Configura il modulo IIS", + "body": "Modifica C:\\Program Files\\UTMStack\\UTMStack Agent\\beats\\filebeat\\modules.d\\iis.yml come mostrato di seguito per puntare alle directory di log IIS che vuoi inviare." + }, + "activate": { + "title": "3 · Attiva", + "body": "Attiva il modulo UTMStack per avviare il flusso degli eventi IIS." + } + } + }, + "filebeat": { + "sections": { + "installRsyslog": { + "title": "1 · Installa rsyslog", + "body": "Assicurati che rsyslog sia installato sull'host. Usa il gestore pacchetti della tua distribuzione (apt, dnf, yum)." + }, + "configureRsyslog": { + "title": "2 · Configura rsyslog per inviare a UTMStack", + "body": "Modifica /etc/rsyslog.conf (o un file sotto /etc/rsyslog.d/) e aggiungi una regola di inoltro che punti all'agente UTMStack tramite UDP o TCP sulla porta 514." + }, + "restartRsyslog": { + "title": "3 · Riavvia rsyslog", + "body": "Riavvia il servizio rsyslog: sudo systemctl restart rsyslog" + }, + "enableCollector": { + "title": "4 · Abilita il raccoglitore di log Linux", + "body": "Abilita il raccoglitore di log e l'integrazione Linux Logs nel file di configurazione in cui è installato l'agente UTMStack." + } + } + }, + "json": { + "sections": { + "overview": { + "title": "1 · Usa l'endpoint di ingestione HTTP/JSON", + "body": "UTMStack accetta eventi JSON arbitrari tramite HTTPS. Invia una richiesta POST con un elenco di eventi; UTMStack li analizza e li instrada tramite il parser configurato." + }, + "auth": { + "title": "2 · Autentica con un token di federazione", + "body": "Ottieni un token di federazione da Settings → Connection Key e invialo come token Bearer nell'intestazione Authorization." + } + }, + "endpoint": { + "title": "Endpoint di ingestione JSON", + "hint": "Usa questo formato di richiesta dalla tua applicazione o da un cron job. Il token è la chiave di federazione da Settings → Connection Key." + } + }, + "ldap": { + "sections": { + "openServerManager": { + "title": "1 · Apri Server Manager", + "body": "Nel controller di dominio AD, apri Server Manager." + }, + "addRoles": { + "title": "2 · Aggiungi ruoli e funzionalità", + "body": "Scegli \"Add roles and features\" dal menu Manage." + }, + "selectCertServices": { + "title": "3 · Seleziona Active Directory Certificate Services", + "body": "Nella fase Server Roles, seleziona Active Directory Certificate Services." + }, + "installServices": { + "title": "4 · Installa il servizio ruolo Certificate Authority", + "body": "Nella fase Role Services, seleziona Certificate Authority e completa la procedura guidata." + }, + "configureAdCs": { + "title": "5 · Configura AD CS", + "body": "Dopo l'installazione, fai clic sulla notifica per configurare AD CS e scegli Certificate Authority come servizio ruolo da configurare." + }, + "pickCaType": { + "title": "6 · Scegli il tipo di CA", + "body": "Scegli Enterprise CA → Root CA → Create a new private key." + }, + "setValidity": { + "title": "7 · Imposta il periodo di validità del certificato", + "body": "Imposta un periodo di validità adeguato alla tua organizzazione (5 anni è tipico)." + }, + "confirm": { + "title": "8 · Conferma e installa", + "body": "Rivedi le impostazioni e fai clic su Configure per terminare." + }, + "restart": { + "title": "9 · Riavvia il controller di dominio", + "body": "Riavvia il controller di dominio affinché LDAPS diventi disponibile su TCP 636." + }, + "activate": { + "title": "10 · Attiva", + "body": "Attiva il modulo UTMStack per avviare il flusso degli eventi di audit AD." + } + } + }, + "oracle": { + "source": "Server Oracle DB", + "step1": { + "title": "Abilita l'integrazione Oracle sul Collector", + "body": "Sul server in cui è installato il Collector, esegui il seguente comando per avviare l'ascolto dei log Oracle:", + "note": "Il Collector inizierà a ricevere eventi syslog da Oracle sulla porta 7021." + }, + "step2": { + "title": "Configura rsyslog sul server Oracle", + "body": "Crea il file di configurazione rsyslog:", + "editBody": "Apri il file con l'editor preferito e aggiungi la seguente configurazione. Sostituisci BASEDIR con il percorso di installazione di Oracle (es. /u01/app/oracle) e con l'indirizzo IP o il nome host del Collector:", + "note": "Usa @@:7021 invece di @ se preferisci la consegna via TCP." + }, + "step3": { + "title": "Riavvia rsyslog", + "body": "Applica la nuova configurazione riavviando il servizio rsyslog:" + }, + "step4": { + "title": "Convalida la configurazione", + "body": "Invia messaggi di log di test per verificare che UTMStack stia ricevendo eventi da tutte e tre le sorgenti di log Oracle:", + "note": "Apri Log Explorer e cerca il testo del messaggio di test sopra per confermare l'arrivo degli eventi." + } + }, + "vulnerabilities": { + "sections": { + "overview": { + "title": "1 · Informazioni sullo scanner delle vulnerabilità", + "body": "Il modulo vulnerabilità di UTMStack esegue la scansione degli asset scoperti tramite il modulo Asset Management e ne confronta l'impronta con il database CVE." + }, + "scope": { + "title": "2 · Definisci l'ambito di scansione", + "body": "Usa il modulo Asset Management per registrare gli host che vuoi sottoporre a scansione. Lo scanner delle vulnerabilità verrà eseguito periodicamente su di essi." + }, + "activate": { + "title": "3 · Attiva", + "body": "Attiva il modulo UTMStack per avviare la scansione." + } + } + }, + "assetScanner": { + "sections": { + "overview": { + "title": "1 · Informazioni su Asset Management", + "body": "Il modulo Asset Management scopre e inventaria host, software e servizi nella rete." + }, + "agentRequirement": { + "title": "2 · Requisito agente", + "body": "Il rilevamento degli asset utilizza agenti UTMStack in esecuzione su host Linux, Windows o macOS. Installa l'agente sui sistemi che desideri inventariare." + }, + "activate": { + "title": "3 · Attiva", + "body": "Attiva il modulo UTMStack per avviare il rilevamento degli asset." + } + } + }, + "fileIntegrity": { + "sections": { + "enableAuditPolicy": { + "title": "1 · Abilita il controllo dell'accesso agli oggetti", + "body": "Sull'host Windows, apri Criteri di gruppo → Configurazione computer → Impostazioni di Windows → Impostazioni di sicurezza → Configurazione avanzata criteri di controllo → Accesso agli oggetti e abilita \"Controlla file system\"." + }, + "configureFolderAuditing": { + "title": "2 · Configura il controllo delle cartelle", + "body": "Per ogni cartella che desideri monitorare, apri Proprietà → Sicurezza → Avanzate → Controllo e aggiungi una voce di controllo per le entità e i tipi di accesso desiderati." + }, + "verifyEvents": { + "title": "3 · Verifica la presenza degli eventi nel registro di sicurezza", + "body": "Apri il Visualizzatore eventi e verifica che gli eventi 4663/4670 vengano generati quando si accede agli oggetti controllati." + }, + "activate": { + "title": "4 · Attiva", + "body": "Attiva il modulo UTMStack affinché gli eventi di integrità dei file inizino a fluire." + } + } + }, + "socAi": { + "sections": { + "overview": { + "title": "1 · Informazioni su SOC AI", + "body": "SOC AI potenzia UTMStack con un analista basato su LLM che sintetizza gli avvisi e suggerisce i passi successivi. Opera tramite il provider che configuri." + }, + "chooseProvider": { + "title": "2 · Scegli un provider", + "body": "Seleziona un provider — OpenAI, Anthropic, Azure OpenAI, Google Gemini, Ollama, Mistral, DeepSeek, Groq o un endpoint personalizzato compatibile con OpenAI." + }, + "configureCredentials": { + "title": "3 · Configura le credenziali", + "body": "Fornisci la chiave API e, dove applicabile, il nome del modello e l'URL dell'endpoint." + }, + "activate": { + "title": "4 · Attiva", + "body": "Attiva il modulo UTMStack affinché SOC AI inizi a elaborare gli avvisi." + } + } + }, + "utmstack": { + "intro": { + "title": "Come funziona", + "body": "Questa integrazione monitora autonomamente il tuo deployment UTMStack. Un collector leggero installato sull'host UTMStack segue i log dei container Docker della piattaforma e li invia nuovamente a UTMStack per la correlazione e la generazione di avvisi.", + "diagram": { + "source": "Log Docker", + "sourceSub": "Container UTMStack", + "edge1": "tail", + "collector": "Collector", + "collectorSub": "sull'host", + "edge2": "invia", + "utmstackSub": "Correla e genera avvisi" + } + }, + "requirements": { + "title": "Disponibile solo sull'host UTMStack", + "body": "Questa integrazione può essere installata solo su un'istanza UTMStack che esegue Ubuntu o una distribuzione della famiglia Red Hat. Installa il collector direttamente sul server UTMStack." + }, + "install": { + "title": "Installa il collector", + "body": "Sull'host UTMStack, seleziona il sistema operativo ed esegui il comando seguente per scaricare e installare il collector di auto-monitoraggio:", + "sensitiveWarning": "Questo comando contiene un token di connessione sensibile. Trattalo come una password e non condividerlo." + }, + "after": { + "title": "Cosa vedrai dopo l'installazione", + "item1": "Il collector si registra e appare nella sezione Sorgenti dati.", + "item2": "I log dei container UTMStack iniziano a fluire entro un minuto.", + "item3": "Gli eventi diventano ricercabili in Log Explorer con il tipo di dato utmstack." + }, + "uninstall": { + "title": "Disinstalla il collector", + "body": "Per rimuovere il collector di auto-monitoraggio dall'host UTMStack, esegui:" + } + }, + "windowsFaa": { + "sections": { + "enableAuditPolicy": { + "title": "1 · Abilita il controllo dell'accesso agli oggetti", + "body": "Sull'host Windows, apri Criteri di gruppo → Configurazione computer → Impostazioni di Windows → Impostazioni di sicurezza → Configurazione avanzata criteri di controllo → Accesso agli oggetti e abilita \"Controlla file system\"." + }, + "configureFolderAuditing": { + "title": "2 · Configura il controllo delle cartelle", + "body": "Per ogni cartella che desideri monitorare, apri Proprietà → Sicurezza → Avanzate → Controllo e aggiungi una voce di controllo per le entità e i tipi di accesso desiderati." + }, + "activate": { + "title": "3 · Attiva", + "body": "Attiva il modulo UTMStack affinché gli eventi di attività sui file inizino a fluire." + } + } + }, + "awsBeanstalk": { + "sections": { + "openConsole": { + "title": "1 · Apri la console Elastic Beanstalk", + "body": "Nella console AWS, apri Elastic Beanstalk." + }, + "environment": { + "title": "2 · Apri la pagina di gestione dell'ambiente", + "body": "Accedi alla pagina di gestione dell'ambiente che desideri monitorare." + }, + "configuration": { + "title": "3 · Apri Configurazione", + "body": "Seleziona Configurazione." + }, + "software": { + "title": "4 · Modifica la configurazione Software", + "body": "Nella categoria di configurazione Software, seleziona Modifica." + }, + "s3LogStorage": { + "title": "5 · Abilita l'archiviazione log su S3", + "body": "Nella sezione Archiviazione log S3, seleziona Ruota log per caricare i log ruotati su Amazon S3." + }, + "cloudwatchStreaming": { + "title": "6 · Abilita lo streaming CloudWatch Logs", + "body": "Nella sezione Streaming log istanza su CloudWatch Logs, abilita lo streaming, imposta il periodo di conservazione e scegli se caricare i log esistenti." + }, + "activate": { + "title": "7 · Attiva", + "body": "Attiva il modulo UTMStack affinché gli eventi di Beanstalk inizino a fluire." + } + } + }, + "awsFargate": { + "sections": { + "taskDefinition": { + "title": "1 · Aggiorna la definizione del task", + "body": "Nella definizione del task Fargate, imposta il logDriver su \"awslogs\" e definisci il nome del gruppo di log." + }, + "cloudwatchLogs": { + "title": "2 · Verifica che CloudWatch Logs stia ricevendo i log", + "body": "Apri la console CloudWatch Logs e verifica che il gruppo di log venga popolato quando i task sono in esecuzione." + }, + "iamPrerequisite": { + "title": "3 · Prerequisito utente IAM", + "body": "Questa integrazione condivide le credenziali con il modulo AWS IAM User — assicurati che sia configurato con CloudWatchLogsReadOnlyAccess." + }, + "activate": { + "title": "4 · Attiva", + "body": "Attiva il modulo UTMStack affinché gli eventi di Fargate inizino a fluire." + } + } + }, + "awsIamUser": { + "sections": { + "iamConsole": { + "title": "1 · Apri la console IAM", + "body": "Nella console AWS, vai su IAM → Utenti → Aggiungi utenti." + }, + "createUser": { + "title": "2 · Crea l'utente", + "body": "Scegli un nome utente (ad es. utmstack-ingest). Seleziona l'accesso programmatico." + }, + "programmaticAccess": { + "title": "3 · Imposta il tipo di credenziale", + "body": "Seleziona \"Chiave di accesso — Accesso programmatico\"." + }, + "attachPolicy": { + "title": "4 · Associa la policy di lettura CloudWatch", + "body": "Associa la policy gestita da AWS CloudWatchLogsReadOnlyAccess." + }, + "review": { + "title": "5 · Verifica l'utente", + "body": "Verifica i dettagli dell'utente e clicca su Crea utente." + }, + "copyKeys": { + "title": "6 · Copia l'ID chiave di accesso e il segreto", + "body": "Copia l'ID chiave di accesso e la Chiave di accesso segreta — il segreto viene mostrato una sola volta." + }, + "createLogGroup": { + "title": "7 · Crea un gruppo di log CloudWatch", + "body": "In CloudWatch → Gruppi di log, crea un gruppo di log denominato \"utmstack\" — le altre integrazioni AWS lo utilizzeranno come destinazione." + }, + "fillForm": { + "title": "8 · Compila il modulo", + "body": "Fornisci a UTMStack la chiave di accesso, il segreto, la regione predefinita e il nome del gruppo di log (ad es. \"utmstack\")." + }, + "activate": { + "title": "9 · Attiva", + "body": "Attiva il modulo UTMStack affinché gli eventi AWS inizino a fluire." + } + } + }, + "awsLambda": { + "sections": { + "iamPrerequisite": { + "title": "1 · Prerequisito utente IAM", + "body": "Lambda si basa sul modulo AWS IAM User — assicurati che tale integrazione sia configurata in anticipo con CloudWatchLogsReadOnlyAccess." + }, + "cloudwatchStream": { + "title": "2 · Lambda invia già dati in streaming a CloudWatch Logs", + "body": "AWS Lambda pubblica automaticamente i log di esecuzione su CloudWatch Logs in /aws/lambda/. UTMStack acquisisce i dati dal gruppo di log configurato durante la configurazione dell'utente IAM." + }, + "activate": { + "title": "3 · Attiva", + "body": "Attiva il modulo UTMStack affinché gli eventi Lambda inizino a fluire." + } + } + }, + "awsSqlServer": { + "sections": { + "openRds": { + "title": "1 · Apri la console Amazon RDS", + "body": "Apri https://console.aws.amazon.com/rds/." + }, + "pickDb": { + "title": "2 · Seleziona l'istanza DB", + "body": "Nel pannello di navigazione, seleziona Database e scegli l'istanza DB che desideri monitorare." + }, + "modify": { + "title": "3 · Modifica l'istanza", + "body": "Seleziona Modifica." + }, + "logExports": { + "title": "4 · Abilita l'esportazione dei log", + "body": "Nella sezione Esportazioni log, seleziona Log degli errori e Log dell'agente per pubblicarli su CloudWatch Logs." + }, + "apply": { + "title": "5 · Applica le modifiche", + "body": "Scegli Continua, poi Modifica istanza DB nella pagina di riepilogo." + }, + "activate": { + "title": "6 · Attiva", + "body": "Attiva il modulo UTMStack affinché gli eventi SQL Server inizino a fluire." + } + } + }, + "awsPostgresql": { + "sections": { + "openRds": { + "title": "1 · Apri la console Amazon RDS", + "body": "Apri https://console.aws.amazon.com/rds/." + }, + "pickDb": { + "title": "2 · Seleziona l'istanza DB", + "body": "Nel pannello di navigazione, scegli Database e seleziona l'istanza DB che vuoi modificare." + }, + "logExports": { + "title": "3 · Abilita le esportazioni log", + "body": "Nella sezione Esportazioni log, scegli il log PostgreSQL da pubblicare su CloudWatch Logs." + }, + "apply": { + "title": "4 · Applica le modifiche", + "body": "Scegli Continua, poi Modifica istanza DB nella pagina di riepilogo." + }, + "activate": { + "title": "5 · Attiva", + "body": "Attiva il modulo UTMStack affinché gli eventi PostgreSQL inizino a fluire." + } + } + }, + "awsTrafficMirror": { + "sections": { + "createTarget": { + "title": "1 · Crea un target di mirroring del traffico", + "body": "Nella console VPC, crea un Traffic Mirror Target che punta all'interfaccia di rete della VM dell'agente UTMStack." + }, + "createFilter": { + "title": "2 · Crea un filtro di mirroring del traffico", + "body": "Crea un Traffic Mirror Filter e aggiungi regole in entrata/uscita per i protocolli da mirrorare (ad es. tutto TCP, tutto UDP)." + }, + "createSession": { + "title": "3 · Crea una sessione di mirroring del traffico", + "body": "Crea una Traffic Mirror Session che associa ciascuna interfaccia di rete sorgente al target e al filtro creati." + }, + "iamPrerequisite": { + "title": "4 · Prerequisito utente IAM", + "body": "Assicurati che anche il modulo AWS IAM User sia configurato, in modo che UTMStack possa leggere i log di flusso VPC se necessario." + }, + "activate": { + "title": "5 · Attiva", + "body": "Attiva il modulo UTMStack affinché il traffico mirrorato inizi ad essere analizzato." + } + } + }, + "forwarder": { + "intro": { + "title": "Come funziona", + "body": "I log fluiscono da {{source}} al UTMStack Collector, che li trasmette in modo sicuro a UTMStack per la correlazione e gli avvisi. Non viene installato nulla su {{source}} — è sufficiente che il Collector sia in esecuzione su un host della tua rete." + }, + "diagram": { + "sourceSub": "i tuoi log", + "forwarder": "Collector", + "forwarderSub": "in ascolto su {{port}}", + "utmstack": "UTMStack", + "utmstackSub": "avvisi e correlazione", + "flow1": "log", + "flow2": "sicuro" + }, + "noInstall": "Non viene installato nulla su {{source}} — è sufficiente reindirizzare i log al Collector.", + "install": { + "title": "Installa il UTMStack Collector", + "body": "Il Collector è un servizio Linux che riceve i log dai tuoi dispositivi e li invia a UTMStack. Un singolo Collector gestisce più integrazioni contemporaneamente.", + "reuse": "Hai già un Collector in esecuzione? Salta questo passaggio — punta {{source}} su quello esistente usando l'host e la porta indicati di seguito." + }, + "tls": { + "title": "Facoltativo — Abilita la cifratura TLS", + "intro": "Per impostazione predefinita, il listener accetta TCP/UDP non cifrato. Per cifrare il traffico syslog in transito, carica prima i tuoi file di certificato, poi riabilita il listener con il protocollo tls.", + "step1": "1 · Carica il tuo certificato e la chiave (una volta per Collector)", + "step1Note": "È possibile aggiungere un certificato CA facoltativo come terzo argomento. Omettilo per utilizzare il certificato foglia come CA.", + "step2": "2 · Riabilita il listener usando TLS" + }, + "httpsCerts": { + "title": "Carica il certificato TLS sul Collector", + "body": "Questa integrazione usa un listener HTTPS sulla porta {{port}}, quindi il Collector richiede un certificato e una chiave caricati prima di abilitarla:" + }, + "uninstall": { + "title": "Facoltativo — Disinstalla il Collector", + "body": "Esegui questo comando sull'host in cui è installato il Collector per interrompere il servizio e rimuovere tutti i suoi file." + }, + "instanceHeader": { + "title": "Intestazione di autorizzazione", + "body": "Includi questa intestazione Authorization in ogni richiesta inviata all'istanza. Il segreto della chiave API viene rivelato una sola volta al momento della sua generazione — copialo allora e incollalo al posto del segnaposto qui sotto.", + "tabSimple": "Semplice", + "tabBatch": "Batch" + }, + "manualCommand": { + "title": "Optional — Enable via the command line instead", + "intro": "Prefer the terminal? SSH into the Collector host and run the command below — it matches whatever protocol and port you have selected above.", + "certStep": "1 · Load your certificate and key (once per Collector)", + "enableStep": "2 · Enable the integration" + } + }, + "aix": { + "source": "Server AIX", + "step1": { + "title": "Abilita il listener AIX sul Collector", + "body": "Sull'host in cui è installato il Collector, esegui questo comando per aprire il listener di log AIX:", + "note": "Per usare TCP invece di UDP, sostituisci udp con tcp nel comando precedente." + }, + "step2": { + "title": "Configura AIX per l'inoltro dei log", + "body": "Sul tuo sistema AIX, configura il servizio syslog per reindirizzare i log all'host del Collector sulla porta {{port}}. Consulta la documentazione IBM per la sintassi esatta — varia tra le versioni AIX." + } + }, + "deceptivebytes": { + "source": "Deceptive Bytes", + "step1": { + "title": "Abilita il listener Deceptive Bytes sul Collector", + "body": "Sull'host in cui è installato il Collector, esegui questo comando per aprire il listener syslog Deceptive Bytes:", + "note": "Per usare TCP invece di UDP, sostituisci udp con tcp nel comando precedente." + }, + "step2": { + "title": "Configura Deceptive Bytes per l'inoltro dei log", + "body": "Nella console di gestione Deceptive Bytes, configura l'inoltro syslog per inviare gli eventi all'host del Collector sulla porta {{port}} (UDP). Deceptive Bytes emette syslog in formato CEF, che il Collector acquisisce come tipo di dato deceptive-bytes." + } + }, + "mikrotik": { + "source": "Router MikroTik", + "step1": { + "title": "Abilita il listener MikroTik sul Collector", + "body": "Sull'host in cui è installato il Collector, esegui questo comando per aprire il listener syslog MikroTik:", + "note": "Per usare TCP invece di UDP, sostituisci udp con tcp nel comando precedente." + }, + "step2": { + "title": "Configura MikroTik per l'inoltro dei log", + "body": "Sul router MikroTik, crea una logging action remota che punta all'host del Collector sulla porta {{port}} e associala agli argomenti log pertinenti. Esegui quanto segue dalla CLI RouterOS (Terminal in Winbox):", + "note": "Puoi anche configurarlo tramite Winbox: System → Logging → scheda Actions (aggiungi un'azione Remote) → poi la scheda Rules (aggiungi regole che puntano alla nuova azione)." + } + }, + "fortigate": { + "source": "Firewall FortiGate", + "step1": { + "title": "Abilita il listener FortiGate sul Collector", + "body": "Sull'host in cui è installato il Collector, esegui questo comando per aprire il listener syslog FortiGate:", + "note": "Per usare TCP invece di UDP, sostituisci udp con tcp nel comando precedente." + }, + "step2": { + "title": "Configura FortiGate per l'inoltro dei log", + "body": "Sul FortiGate, punta syslog all'host del Collector sulla porta {{port}}. Esegui quanto segue dalla CLI FortiOS (o usa Log & Report → Log Settings → Syslog nella GUI):", + "note": "Sostituisci l'indirizzo del server se il Collector è in esecuzione su un host diverso. Per più collector syslog usa syslogd2/syslogd3/syslogd4." + } + }, + "fortiweb": { + "source": "FortiWeb WAF", + "step1": { + "title": "Abilita il listener FortiWeb sul Collector", + "body": "Sull'host in cui è installato il Collector, esegui questo comando per aprire il listener syslog FortiWeb:", + "note": "Per usare TCP invece di UDP, sostituisci udp con tcp nel comando precedente." + }, + "step2": { + "title": "Configura FortiWeb per l'inoltro dei log", + "body": "Sul FortiWeb, crea una policy syslog che punta all'host del Collector sulla porta {{port}} e abilita il logging syslog. Esegui quanto segue dalla CLI FortiWeb (o usa Log & Report → Log Policy → Syslog Policy nella GUI):", + "note": "Assicurati che i tipi di log pertinenti (Attack, Event, Traffic) siano abilitati per l'invio a syslog nelle impostazioni Log & Report." + } + }, + "paloalto": { + "source": "Firewall Palo Alto", + "step1": { + "title": "Abilita il listener Palo Alto sul Collector", + "body": "Sull'host in cui è installato il Collector, esegui questo comando per aprire il listener syslog Palo Alto:", + "note": "Per usare TCP invece di UDP, sostituisci udp con tcp nel comando precedente." + }, + "step2": { + "title": "Crea un profilo server Syslog", + "body": "In PAN-OS, vai su Device → Server Profiles → Syslog e aggiungi un profilo. Imposta l'indirizzo del server su {{host}}, trasporto UDP, porta {{port}} e formato BSD." + }, + "step3": { + "title": "Invia log e applica le modifiche", + "body": "Crea un profilo Log Forwarding (Objects → Log Forwarding) che invia log di tipo Traffic, Threat e altri al profilo syslog sopra, associalo alle tue regole Security policy (Policies → Security → regola → Actions → Log Forwarding), quindi esegui Commit." + } + }, + "pfsense": { + "source": "Firewall pfSense", + "step1": { + "title": "Abilita il listener pfSense sul Collector", + "body": "Sull'host in cui è installato il Collector, esegui questo comando per aprire il listener syslog pfSense:", + "note": "Per usare TCP invece di UDP, sostituisci udp con tcp nel comando precedente." + }, + "step2": { + "title": "Abilita il logging remoto in pfSense", + "body": "Nell'interfaccia web pfSense, vai su Status → System Logs → Settings. In Remote Logging Options, spunta Enable Remote Logging, imposta un server di log remoto su {{host}}:{{port}}, scegli quali log inviare (o Everything), e clicca Save." + } + }, + "sonicwall": { + "source": "Firewall SonicWall", + "step1": { + "title": "Abilita il listener SonicWall sul Collector", + "body": "Sull'host in cui è installato il Collector, esegui questo comando per aprire il listener syslog SonicWall:", + "note": "Per usare TCP invece di UDP, sostituisci udp con tcp nel comando precedente." + }, + "step2": { + "title": "Aggiungi un server Syslog in SonicOS", + "body": "In SonicOS, vai su Device → Log → Syslog (Manage → Log → Syslog nei firmware meno recenti) e aggiungi un server Syslog con indirizzo {{host}} e porta {{port}}. Imposta il Syslog Format su ArcSight (CEF) — UTMStack analizza SonicWall in CEF — poi clicca Apply." + } + }, + "sophosxg": { + "source": "Sophos Firewall", + "step1": { + "title": "Abilita il listener Sophos Firewall sul Collector", + "body": "Sull'host in cui è installato il Collector, esegui questo comando per aprire il listener syslog Sophos Firewall:", + "note": "Per usare TCP invece di UDP, sostituisci udp con tcp nel comando precedente." + }, + "step2": { + "title": "Aggiungi un server Syslog in Sophos Firewall", + "body": "Nella console Sophos Firewall (SFOS), vai su System → System services → Log settings e aggiungi un server Syslog con indirizzo {{host}} e porta {{port}}. Scegli i tipi di log da inoltrare (firewall, IPS, ATP, web, ecc.) e clicca su Apply." + } + }, + "suricata": { + "source": "Suricata IDS", + "step1": { + "title": "Abilita il listener Suricata sul Collector", + "body": "Sull'host in cui è installato il Collector, esegui questo comando per aprire il listener Suricata:", + "note": "Per usare TCP al posto di UDP, sostituisci udp con tcp nel comando precedente." + }, + "step2": { + "title": "Invia i log Suricata EVE a syslog", + "body": "Suricata viene acquisito come JSON (EVE). Sull'host Suricata, modifica suricata.yaml e configura l'output eve-log per scrivere su syslog:", + "note": "Quindi riavvia Suricata: sudo systemctl restart suricata" + }, + "step3": { + "title": "Inoltra syslog al Collector", + "body": "Punta la facility local5 (dove Suricata scrive ora) verso il Collector. Aggiungi questa regola in /etc/rsyslog.d/60-utmstack-suricata.conf sull'host Suricata:", + "note": "Usa @@ al posto di @ per TCP. Quindi riavvia rsyslog: sudo systemctl restart rsyslog" + } + }, + "o365_graph": { + "intro": { + "title": "Come funziona", + "body": "UTMStack si connette a Microsoft 365 con un'app Azure AD registrata e interroga Microsoft Graph per gli eventi di sicurezza: allerte, incidenti, audit del directory, sign-in, rilevamenti di rischio, query di hunting e log di audit Purview. Non viene installato alcun agente nel tuo tenant.", + "diagram": { + "source": "eventi di sicurezza", + "edge": "Microsoft Graph", + "utmstackSub": "correlazione & allerte" + }, + "note": "UTMStack richiede solo accesso in sola lettura all'API Graph — non vengono richieste autorizzazioni di scrittura." + }, + "appSection": "Registrazione app Azure", + "steps": { + "azurePortal": { + "title": "Apri Microsoft Entra ID", + "body": "Apri il Portale di Azure (portal.azure.com) e clicca su Microsoft Entra ID." + }, + "appRegistrations": { + "title": "Vai a Registrazioni app", + "body": "Nel menu a sinistra, clicca su Registrazioni app." + }, + "registerApp": { + "title": "Registra una nuova app", + "body": "Clicca su Nuova registrazione. Nominala UTMStack Graph Dev, seleziona Solo account in questo directory organizzativo (Single-tenant) e clicca su Registra." + }, + "clientSecret": { + "title": "Crea un segreto client", + "body": "Vai su Certificati e segreti → Nuovo segreto client. Aggiungi una descrizione, imposta la scadenza su 730 giorni (24 mesi) e clicca su Aggiungi.", + "copyNote": "Copia subito il valore del segreto — viene mostrato solo una volta e non potrà essere recuperato in seguito." + }, + "apiPermissions": { + "title": "Aggiungi le autorizzazioni Microsoft Graph", + "body": "Vai su Autorizzazioni API → Aggiungi un'autorizzazione e seleziona Microsoft Graph, poi scegli Autorizzazioni dell'applicazione." + }, + "graphPermissions": { + "title": "Aggiungi le quattro autorizzazioni Graph", + "body": "Aggiungi SecurityEvents.Read.All, Directory.Read.All, AuditLog.Read.All e IdentityRiskEvent.Read.All." + }, + "adminConsent": { + "title": "Concedi il consenso amministratore", + "body": "Tornato in Autorizzazioni API, clicca su Concedi consenso amministratore per {tenant} e conferma." + }, + "noteIds": { + "title": "Copia gli ID dell'app", + "body": "Vai alla Panoramica dell'app e copia l'ID applicazione (client) e l'ID directory (tenant). Ti serve anche il valore del segreto copiato al passaggio 4." + } + }, + "credentialsSection": "Credenziali", + "credentials": { + "title": "Connetti il tuo tenant Microsoft 365", + "body": "Inserisci i dettagli dai passaggi sopra. UTMStack verifica le credenziali prima di salvarle. Puoi aggiungere più gruppi di configurazione." + }, + "fields": { + "tenantId": { + "label": "ID Tenant (ID Directory)" + }, + "clientId": { + "label": "ID Client (ID Applicazione)" + }, + "clientSecret": { + "label": "Segreto Client" + }, + "cloudEnv": { + "label": "Ambiente cloud (facoltativo)", + "hint": "Commercial (default), GCC, GCCHigh o DoD" + } + } + } + }, + "cloud": { + "howItWorksTitle": "Come funziona", + "howItWorksBody": "{{name}} viene eseguito completamente all'interno di UTMStack — nessun agente o collector da distribuire. Fornisci credenziali API di sola lettura e UTMStack estrarrà gli eventi in base a una pianificazione, li analizzerà e li ingerirà in Log Explorer.", + "connectionTitle": "Connessione", + "noFields": "Nessun campo di connessione configurato.", + "testConnection": "Prova connessione", + "save": "Salva", + "afterTitle": "Cosa vedrai dopo la connessione", + "after1": "UTMStack esegue un recupero iniziale degli eventi recenti.", + "after2": "Da allora in poi, gli eventi vengono estratti ogni 1–5 minuti (dipende dall'API).", + "after3": "L'integrazione appare sotto Origini dati con lo stato di estrazione attuale e il ritardo.", + "tenants": { + "title": "Gruppi di configurazione configurati", + "empty": "Nessun gruppo di configurazione. Aggiungi il primo qui sotto.", + "loading": "Caricamento gruppi di configurazione…", + "nameLabel": "Nome del gruppo di configurazione", + "namePlaceholder": "es. acme-prod", + "add": "Aggiungi gruppo di configurazione", + "update": "Aggiorna gruppo di configurazione", + "delete": "Elimina", + "edit": "Modifica", + "cancel": "Annulla", + "editing": "Modifica: {{name}}", + "selectFile": "Seleziona file", + "replaceFile": "Sostituisci file", + "fileLoaded": "File caricato", + "invalidJson": "Impossibile interpretare il file come JSON.", + "createError": "Impossibile creare il gruppo di configurazione. Riprova.", + "updateError": "Impossibile aggiornare il gruppo di configurazione. Riprova.", + "createSuccess": "Gruppo di configurazione creato con successo.", + "updateSuccess": "Gruppo di configurazione aggiornato con successo." + }, + "google": { + "sections": { + "createTopic": { + "title": "1 · Crea un argomento Pub/Sub", + "body": "Nella console di Google Cloud, apri Pub/Sub → Argomenti e crea un nuovo argomento. UTMStack riceverà gli eventi tramite questo argomento.", + "docLabel": "Apri la pagina dei topic Pub/Sub" + }, + "createSubscription": { + "title": "2 · Crea una sottoscrizione", + "body": "All'interno dell'argomento, crea una sottoscrizione di tipo Pull. UTMStack preleva i messaggi da questa sottoscrizione." + }, + "configureSubscription": { + "title": "3 · Configura la sottoscrizione", + "body": "Imposta la durata di conservazione dei messaggi su un valore adatto alla tua tolleranza di disservizio (7 giorni di default va bene). Lascia la scadenza di conferma a 10 secondi e l'expiration su «Mai»." + }, + "logsRouter": { + "title": "4 · Apri il Logs Router", + "body": "Vai in Logging → Logs Router e crea un nuovo sink. È quello che inoltra i log del progetto all'argomento Pub/Sub creato sopra." + }, + "sinkDestination": { + "title": "5 · Punta il sink all'argomento", + "body": "Scegli Argomento Cloud Pub/Sub come destinazione del sink e seleziona l'argomento creato. Usa i filtri di inclusione/esclusione per limitare cosa viene inoltrato." + }, + "serviceAccount": { + "title": "6 · Crea un service account", + "body": "Apri IAM e amministrazione → Service account e crea un nuovo service account. Assegnagli il ruolo Editor Pub/Sub in modo che UTMStack possa leggere dalla sottoscrizione.", + "docLabel": "Apri la pagina degli account di servizio" + }, + "serviceAccountKey": { + "title": "7 · Genera una chiave per il service account", + "body": "Apri il service account, vai alla scheda Chiavi e aggiungi una nuova chiave. Scegli JSON come tipo di chiave." + }, + "downloadKey": { + "title": "8 · Scarica e carica la chiave JSON", + "body": "Salva il file JSON scaricato da Google: il contenuto va nel campo «Chiave JSON del service account» qui sotto." + } + }, + "fields": { + "projectId": { + "label": "ID progetto" + }, + "subscription": { + "label": "Nome sottoscrizione" + }, + "jsonKey": { + "label": "Chiave JSON del service account" + } + }, + "intro": { + "title": "Come funziona", + "body": "UTMStack legge l'attività di audit direttamente da Google Cloud tramite Pub/Sub. Un sink del Logs Router instrada i log del progetto in un topic Pub/Sub; UTMStack esegue un puller interno che legge una Pull subscription su quel topic utilizzando la chiave dell'account di servizio. Non viene installato nulla nel progetto GCP.", + "diagram": { + "source": "Cloud Logging", + "edge1": "Logs Router", + "pubsub": "Pub/Sub", + "pubsubSub": "topic + subscription", + "edge2": "preleva", + "utmstackSub": "alert e correlazione" + }, + "note": "Nessun agente viene eseguito in GCP — UTMStack preleva i messaggi dalla sottoscrizione Pub/Sub utilizzando la chiave JSON dell'account di servizio fornita di seguito." + }, + "credentials": { + "title": "Configurazione Pub/Sub", + "body": "Usa i valori raccolti in precedenza per configurare UTMStack. Puoi monitorare più di un progetto salvando configurazioni aggiuntive.", + "mapping": { + "intro": "Riferimento campi", + "projectId": "Project ID — il progetto GCP che contiene il topic, la sottoscrizione e il sink", + "subscription": "Nome della sottoscrizione — la Pull subscription creata al passaggio 2", + "jsonKey": "Chiave JSON dell'account di servizio — il file scaricato al passaggio 8" + } + } + }, + "azure": { + "sections": { + "sharedAccessPolicy": { + "title": "2 · Aggiungi un criterio di accesso condiviso", + "body": "Apri l'Event Hub → Criteri di accesso condiviso e crea un nuovo criterio con solo il permesso Listen." + }, + "connectionString": { + "title": "3 · Copia la stringa di connessione primaria", + "body": "Apri il criterio e copia la stringa di connessione primaria. È simile a: Endpoint=sb://...;SharedAccessKeyName=...;SharedAccessKey=..." + }, + "consumerGroup": { + "title": "4 · Crea un consumer group dedicato", + "body": "Apri l'Event Hub → Consumer group e creane uno nuovo per UTMStack. Non riutilizzare $Default: dai a UTMStack un proprio gruppo per evitare conflitti di checkpoint con altri consumer.", + "warn": "Crea un consumer group specificamente per UTMStack. Non utilizzare $Default o altri gruppi già in uso — riutilizzare un consumer group tra consumer non correlati può causare comportamenti imprevisti ed eventi persi. Tutte le istanze UTMStack devono condividere lo stesso consumer group per elaborare gli eventi insieme." + }, + "storageContainer": { + "title": "6 · Crea un container nell'account di archiviazione", + "body": "Nell'account di archiviazione → Container, crea un nuovo container. Annota il nome del container e la stringa di connessione dell'account (Chiavi di accesso → Stringa di connessione)." + }, + "eventGrid": { + "title": "7 · Registra il provider di risorse Event Grid", + "body": "In Sottoscrizioni → Provider di risorse, registra Microsoft.EventGrid se non lo è già. Permette ad Azure di inoltrare eventi a livello di sottoscrizione al tuo Event Hub." + }, + "createEventHub": { + "title": "Crea un Event Hub", + "body": "Nel portale Azure, crea un namespace Event Hubs e un Event Hub al suo interno. UTMStack leggerà gli eventi da questo hub.", + "docLabel": "Avvio rapido: Creare un event hub tramite il portale Azure" + }, + "createStorageAccount": { + "title": "Crea un Storage Account", + "body": "UTMStack ha bisogno di un Storage Account per salvare i checkpoint della posizione di lettura. Creane uno nella stessa area geografica dell'Event Hub.", + "docLabel": "Avvio rapido: Creare un account di archiviazione" + }, + "storageConnection": { + "title": "Copia la stringa di connessione del Storage Account", + "body": "Ottieni la stringa di connessione del Storage Account con chiave in: All services → Storage accounts → il tuo account → Access keys. UTMStack la usa per archiviare i checkpoint dell'Event Hub." + }, + "createEventSubscription": { + "title": "Crea una sottoscrizione eventi", + "body": "Nel pannello Events della sottoscrizione, crea un nuovo evento cliccando su Events → Event Subscription." + }, + "configureEventSubscription": { + "title": "Punta la sottoscrizione eventi verso il tuo Event Hub", + "body": "Configura la sottoscrizione eventi per inviare i log all'Event Hub creato al passaggio 1." + } + }, + "fields": { + "eventHubConnection": { + "label": "Stringa di connessione Event Hub" + }, + "consumerGroup": { + "label": "Consumer group" + }, + "storageContainer": { + "label": "Nome del container di archiviazione" + }, + "storageConnection": { + "label": "Stringa di connessione dell'account di archiviazione" + } + }, + "intro": { + "title": "Come funziona", + "body": "UTMStack legge l'attività di audit direttamente da un Azure Event Hub. Configuri la sottoscrizione Azure per trasmettere gli eventi in un Event Hub; UTMStack esegue un puller interno che legge quell'hub e salva i checkpoint in un Storage Account. Non viene installato nulla nel tenant Azure.", + "diagram": { + "source": "eventi della sottoscrizione", + "edge1": "instrada verso", + "eventHub": "Event Hub", + "eventHubSub": "flusso di eventi", + "edge2": "preleva", + "utmstackSub": "alert e correlazione" + }, + "note": "Nessun agente viene eseguito in Azure — UTMStack preleva gli eventi dall'Event Hub utilizzando le stringhe di connessione fornite di seguito." + }, + "sampleLabel": "Esempio di stringa di connessione:", + "credentials": { + "title": "Configurazione Event Hub", + "body": "Usa i dati raccolti nei passaggi precedenti per configurare UTMStack. Puoi aggiungere più di un Event Hub salvando configurazioni aggiuntive.", + "mapping": { + "intro": "Riferimento campi", + "eventHubConnection": "Stringa di connessione Event Hub — valore ottenuto al passaggio 3", + "consumerGroup": "Consumer group — valore ottenuto al passaggio 4", + "storageContainer": "Nome del container di archiviazione — valore ottenuto al passaggio 6", + "storageConnection": "Stringa di connessione dell'account di archiviazione — valore ottenuto al passaggio 7" + } + } + }, + "aws": { + "fields": { + "accessKeyId": { + "label": "ID chiave di accesso AWS" + }, + "secretAccessKey": { + "label": "Chiave di accesso segreta AWS" + }, + "region": { + "label": "Regione AWS predefinita" + }, + "logGroupName": { + "label": "Nome del log group" + } + }, + "intro": { + "title": "Come funziona", + "body": "UTMStack legge l'attività di audit direttamente da AWS CloudWatch Logs. CloudTrail acquisisce le chiamate API e gli eventi di gestione dell'account AWS, li invia a un gruppo di log CloudWatch e UTMStack interroga quel gruppo per acquisire e correlare gli eventi.", + "diagram": { + "source": "eventi API", + "edge1": "CloudTrail", + "cloudwatchSub": "gruppi di log", + "edge2": "interroga", + "utmstackSub": "alert e correlazione" + }, + "note": "Nessun agente viene installato su AWS — UTMStack preleva gli eventi di log utilizzando le credenziali IAM in sola lettura fornite di seguito." + }, + "iamSection": "Configura utente IAM", + "iam": { + "dashboard": { + "title": "Apri il dashboard IAM", + "body": "Apri la console AWS, vai al dashboard IAM e seleziona Users." + }, + "addUser": { + "title": "Aggiungi un utente", + "body": "Clicca su Add user, inserisci un nome utente descrittivo e procedi al passaggio successivo." + }, + "attachPolicy": { + "title": "Associa la policy in sola lettura", + "body": "In Permissions, associa la policy richiesta. Seleziona CloudWatchLogsReadOnlyAccess per l'accesso in sola lettura a CloudWatch." + }, + "createUser": { + "title": "Crea l'utente", + "body": "Rivedi la configurazione e clicca su Create user per eseguire il provisioning dell'account." + }, + "openUser": { + "title": "Apri il nuovo utente", + "body": "Apri l'utente appena creato cliccando sul suo nome per visualizzare i dettagli e gestire le credenziali." + }, + "securityTab": { + "title": "Vai a Security credentials", + "body": "Seleziona la scheda Security credentials per creare chiavi di accesso programmatico." + }, + "createKey": { + "title": "Crea una chiave di accesso", + "body": "Clicca su Create access key e scegli l'opzione per un'applicazione in esecuzione al di fuori di AWS (accesso programmatico)." + }, + "confirmKey": { + "title": "Conferma la creazione", + "body": "Conferma la creazione della chiave di accesso. AWS genererà un Access Key ID e una Secret Access Key." + }, + "downloadKey": { + "title": "Salva le credenziali", + "body": "Scarica il file delle credenziali o copia l'Access Key ID e la Secret Access Key in un luogo sicuro — la Secret Access Key viene mostrata una sola volta." + } + }, + "credentials": { + "title": "Inserisci le credenziali", + "body": "Incolla l'Access Key ID e la Secret Access Key ottenuti nei passaggi precedenti. UTMStack verifica le credenziali con AWS prima di salvarle." + }, + "cloudwatchSection": "Configura AWS CloudWatch", + "cloudwatch": { + "createGroup": { + "title": "Crea un gruppo di log CloudWatch", + "body": "Apri la console CloudWatch, scegli Log management e clicca su Create log group." + }, + "nameGroup": { + "title": "Assegna un nome al gruppo di log e imposta la conservazione", + "body": "Inserisci il nome del gruppo di log utmstack e imposta la conservazione a 1 giorno. Clicca su Create log group." + }, + "openTrail": { + "title": "Apri CloudTrail e crea un trail", + "body": "Nella console CloudTrail, clicca su Create trail per iniziare a configurare un nuovo trail." + }, + "configureTrail": { + "title": "Configura la distribuzione, la validazione e l'integrazione con CloudWatch", + "body": "Nel modulo di creazione CloudTrail, imposta le seguenti opzioni:", + "items": [ + "Nome e ambito del trail: inserisci un nome descrittivo; abilita Apply trail to all accounts in my organization se hai bisogno di una raccolta a livello di organizzazione.", + "Destinazione S3: scegli Create new S3 bucket (o seleziona un bucket esistente) per la distribuzione dei log non elaborati.", + "Crittografia: abilita Log file SSE-KMS e seleziona la chiave KMS appropriata.", + "Validazione file di log: abilita per garantire l'integrità dei log distribuiti (consigliato).", + "CloudWatch Logs: abilita la distribuzione a CloudWatch, seleziona Use existing log group e inserisci il nome esatto utmstack.", + "Ruolo IAM: fornisci o crea il ruolo che CloudTrail assumerà per scrivere su S3 e pubblicare su CloudWatch." + ] + }, + "eventTypes": { + "title": "Seleziona i tipi di evento", + "body": "Abilita le categorie di eventi necessarie per il monitoraggio e la verifica.", + "management": { + "label": "1 · Management events", + "body": "Abilita Management events e seleziona All per registrare tutta l'attività API che gestisce le risorse AWS (creazione, aggiornamento, eliminazione)." + }, + "data": { + "label": "2 · Data events", + "body": "Aggiungi un Data event. Scegli S3 e seleziona Log all events per acquisire operazioni a livello di oggetto come GetObject e PutObject." + }, + "network": { + "label": "3 · Network activity events", + "body": "Nella sezione Network Activities aggiungi almeno un servizio (es. ec2.amazonaws.com) e abilita Log all events." + } + }, + "review": { + "title": "Rivedi e crea il trail", + "body": "Nella schermata Configure event aggregation accetta i valori predefiniti (o modificali se necessario). Rivedi tutte le impostazioni e clicca su Create trail." + } + } + }, + "crowdstrike": { + "intro": { + "title": "Come funziona", + "body": "UTMStack legge rilevamenti e attività di audit direttamente dall'API CrowdStrike Falcon Event Streams. Crei un client API in Falcon con scope Event Streams; UTMStack esegue un puller interno che trasmette in streaming gli eventi usando tali credenziali. Non viene installato nulla sugli endpoint né in Falcon.", + "diagram": { + "source": "rilevamenti ed eventi", + "edge1": "Event Streams API", + "api": "Falcon API", + "apiSub": "event stream", + "edge2": "recupera", + "utmstackSub": "alert e correlazione" + }, + "note": "UTMStack non distribuisce alcun agente — recupera gli eventi da Falcon utilizzando le credenziali del client API in sola lettura fornite di seguito." + }, + "sections": { + "apiClients": { + "title": "Apri API Clients and Keys", + "body": "Nella console Falcon, apri il menu (icona hamburger, in alto a sinistra) e vai su Support and resources → API Clients and Keys." + }, + "createClient": { + "title": "Crea un nuovo client API", + "body": "Clicca su Create API Client per avviare la definizione di un nuovo client." + }, + "scopes": { + "title": "Assegna un nome al client e concedi lo scope Event Streams", + "body": "Assegna al client un nome descrittivo (UTMStack lo usa per identificare la sorgente degli eventi) e seleziona gli scope API richiesti per Event Streams. Clicca su Create per generare le credenziali." + }, + "recordCredentials": { + "title": "Registra le credenziali", + "body": "Copia il Client ID, il Client Secret e il Base URL per la tua regione CrowdStrike. Il segreto viene mostrato una sola volta — conservalo in modo sicuro. Incollerai tutti e tre nel modulo seguente." + } + }, + "credentials": { + "title": "Configurazione del client API", + "body": "Usa le credenziali dei passaggi precedenti per configurare UTMStack. Puoi aggiungere più di un client CrowdStrike salvando configurazioni aggiuntive.", + "mapping": { + "intro": "Riferimento ai campi", + "appName": "App name — nome descrittivo del client dal passaggio 3 (identifica la sorgente degli eventi)", + "clientId": "Client ID — valore registrato al passaggio 4", + "clientSecret": "Client Secret — valore registrato al passaggio 4 (mostrato una sola volta)", + "cloudRegionUrl": "Base URL — endpoint della tua regione, es. https://api.crowdstrike.com (us-1), https://api.us-2.crowdstrike.com (us-2), https://api.eu-1.crowdstrike.com (eu-1)" + } + }, + "fields": { + "appName": { + "label": "App name" + }, + "clientId": { + "label": "Client ID" + }, + "clientSecret": { + "label": "Client Secret" + }, + "cloudRegionUrl": { + "label": "Base URL (regione cloud)" + } + } + } + }, + "custom": { + "whenTitle": "Quando usarlo", + "whenBody": "Quando la tua origine non è nel catalogo. Inoltri syslog o JSON arbitrario a UTMStack e definisci un parser per normalizzare i campi.", + "endpointsTitle": "Endpoint", + "syslogUdp": "Syslog (UDP)", + "syslogTls": "Syslog (TLS)", + "httpJson": "HTTP / JSON", + "payloadTitle": "Esempio di payload JSON", + "parserTitle": "Definisci il parser", + "parserBody": "Gli eventi in ingresso vengono memorizzati sotto il tipo di dato {{dataType}}. Aggiungi un filtro di parsing affinché il payload grezzo venga mappato in campi strutturati, quindi crea regole di avviso.", + "openEditor": "Apri editor parser", + "powershellLabel": "PowerShell (Esegui come amministratore)", + "linuxLabel": "Linux — bash", + "macosLabel": "macOS — bash", + "exampleLabel": "Esempio di destinazione syslog su {{name}}:", + "intro": { + "title": "Come funziona", + "body": "Un'integrazione personalizzata acquisisce i log da qualsiasi sorgente non coperta dai moduli integrati. Installa il UTMStack Collector, registra un listener per i tuoi dati con il protocollo scelto e punta la sorgente verso di esso.", + "note": "Scegli di seguito il protocollo che la tua sorgente può inviare (syslog UDP/TCP/TLS, oppure HTTP/HTTPS per JSON) — il Collector crea automaticamente il tipo di dato." + }, + "diagram": { + "source": "La tua sorgente", + "sourceSub": "qualsiasi app o dispositivo", + "forwarder": "Collector", + "ingests": "acquisisce", + "utmstackSub": "alert e correlazione" + }, + "choose": { + "title": "Scegli protocollo e porta", + "body": "Seleziona come la tua sorgente invia i dati e la porta su cui il Collector deve mettersi in ascolto, quindi esegui il comando di attivazione sull'host del Collector.", + "portLabel": "Porta del listener", + "tlsFirst": "Prima carica il certificato TLS e la chiave sul Collector:", + "enableLabel": "Poi abilita l'integrazione:", + "authNote": "Per richiedere l'autenticazione, aggiungi --auth bearer (token) o --auth hmac — il Collector stampa un token da usare nell'header Authorization." + }, + "send": { + "title": "Punta la sorgente verso il Collector", + "bodyNetwork": "Configura la tua sorgente per inviare syslog {{proto}} a {{host}}:{{port}}. La maggior parte dei dispositivi dispone di un'impostazione remote-syslog o di inoltro log remoto per questo.", + "bodyHttp": "Invia i tuoi eventi come JSON via HTTP POST a {{endpoint}}. Il corpo di ogni richiesta è un evento JSON:", + "httpBindNote": "Il listener HTTP/HTTPS si collega a 127.0.0.1 (l'host del Collector) per impostazione predefinita, quindi invia dall'app in esecuzione su quell'host — oppure usalo con un reverse proxy. Per sorgenti remote, usa syslog (UDP/TCP/TLS)." + }, + "manualCommand": { + "title": "Optional — Enable via the command line instead", + "intro": "Prefer the terminal? SSH into the Collector host and run the command below — it matches whatever protocol and port you have selected above." + } + }, + "remoteEnable": { + "title": "Abilita questa integrazione da remoto", + "body": "Scegli un Collector, scegli il protocollo e la porta, quindi abilita l'integrazione — non è necessario SSH.", + "noPermission": "Non hai il permesso di gestire le integrazioni remote. Chiedi a un amministratore di concedere il permesso integrations.write.", + "loadingCollectors": "Caricamento Collectors…", + "noCollectors": "Nessun Collector è ancora registrato. Installane uno sopra per abilitare le integrazioni da remoto.", + "forwarderOffline": "Questo Collector è offline e non può ricevere modifiche di configurazione in questo momento.", + "legendOnline": "{{count}} online", + "legendOffline": "{{count}} offline", + "legendTotal": "{{count}} totali", + "forwarderLabel": "Collector", + "protoLabel": "Protocollo", + "portLabel": "Porta", + "currentStateLoading": "Verifica della configurazione attuale…", + "currentlyEnabled": "Attualmente: abilitato · {{proto}} · porta {{port}}", + "currentlyDisabled": "Attualmente: disabilitato · {{proto}} · porta {{port}}", + "authLabel": "Autenticazione", + "authNone": "Nessuna", + "authBearer": "Bearer token", + "authHmac": "Firma HMAC", + "pathLabel": "Percorso", + "signatureHeaderLabel": "Header di firma", + "certTitle": "Certificato TLS", + "certLoading": "Verifica dello stato del certificato…", + "certLoaded": "Un certificato valido è già caricato su questo Collector.", + "certMissing": "Nessun certificato caricato ancora — caricane uno per abilitare questo protocollo.", + "certInvalid": "Il certificato caricato non è valido: {{error}}", + "certPemLabel": "Certificato", + "keyPemLabel": "Chiave privata", + "caPemLabel": "Certificato CA", + "uploadCertsButton": "Carica certificato", + "certUploadSuccess": "Certificato caricato.", + "certUploadError": "Caricamento del certificato non riuscito.", + "certReadError": "Non è stato possibile leggere il file o i file selezionati.", + "enableButton": "Abilita integrazione", + "disableButton": "Disabilita integrazione", + "enableSuccess": "Integrazione abilitata.", + "disableSuccess": "Integrazione disabilitata.", + "enableError": "Aggiornamento dell'integrazione non riuscito.", + "secretWarning": "Archivia questo token in modo sicuro — non verrà visualizzato di nuovo.", + "sendToInstance": "Invia all'istanza", + "enterpriseFeature": "Questa è una funzionalità Enterprise.", + "addCollector": "Aggiungi Collector", + "addApiKey": "Aggiungi chiave API", + "apiKeyLabel": "Chiave API", + "apiKeyHint": "Prima ti servirà una chiave API.", + "apiKeyPlaceholder": "Seleziona una chiave API", + "apiKeyAddNew": "Aggiungi chiave API…", + "apiKeyNone": "Nessuna chiave API ancora", + "forwarderNoRemoteControl": "Questo forwarder è stato installato con il controllo remoto disattivato. Ignora la configurazione inviata da qui, e questo si può cambiare solo sulla macchina stessa." + } + }, + "codeBlock": { + "copy": "Copia", + "copied": "Copiato" + }, + "createDrawer": { + "title": "Nuova integrazione personalizzata", + "moduleName": "Nome modulo", + "moduleNameHint": "Identificatore univoco. Senza spazi.", + "moduleNamePlaceholder": "la-mia-app-personalizzata", + "prettyName": "Nome visualizzato", + "prettyNamePlaceholder": "La Mia App Personalizzata", + "dataType": "Tipo di dati", + "dataTypePlaceholder": "Identificatore univoco per questo tipo di dati", + "icon": "Icona", + "iconHint": "PNG, SVG, JPEG, GIF o WEBP. Max 3MB. Usato come logo dell'integrazione.", + "iconPreview": "Anteprima icona", + "dataTypeExists": "Questo tipo di dati esiste già", + "invalidFileType": "L'icona deve essere un file immagine valido (PNG, JPEG, SVG, GIF, WEBP)", + "fileTooLarge": "L'icona non deve superare 3MB", + "fileReadError": "Errore nella lettura del file", + "cancel": "Annulla", + "create": "Crea integrazione", + "creating": "Creazione…", + "editTitle": "Modifica integrazione", + "save": "Salva", + "saving": "Salvataggio…", + "currentIcon": "Icona corrente — carica un file per sostituirla", + "name": "Nome dell'integrazione", + "namePlaceholder": "es. Acme Firewall", + "description": "Descrizione", + "descriptionPlaceholder": "Cosa acquisisce questa integrazione e perché (facoltativo)", + "identifierHint": "Salvato come “{{id}}” (derivato dal nome)", + "nameTaken": "Questo nome di integrazione non può essere utilizzato — esiste già un'integrazione con quell'identificatore.", + "removeIcon": "Rimuovi icona", + "defaultIconNote": "Icona predefinita — carica un file per usare la tua." + }, + "toast": { + "created": "Integrazione creata", + "updated": "Integrazione aggiornata", + "updateError": "Aggiornamento dell'integrazione non riuscito" + }, + "delete": { + "title": "Elimina integrazione", + "confirm": "Eliminare questa integrazione?", + "yes": "Elimina", + "no": "Annulla", + "deleted": "Integrazione eliminata", + "error": "Eliminazione dell'integrazione non riuscita" + }, + "modules": { + "WINDOWS_AGENT": "Raccogli l'attività di sistema Windows, sicurezza e log degli eventi tramite l'agente leggero UTMStack installato su ciascun host.", + "LINUX_AGENT": "Raccogli i log di sistema Linux, autenticazione e audit tramite l'agente leggero UTMStack installato su ciascun host.", + "MACOS": "Raccogli l'attività di log di sistema e sicurezza di macOS dagli endpoint Apple Mac tramite l'agente leggero UTMStack.", + "VMWARE": "Acquisisci il syslog dell'hypervisor VMware ESXi in modo che l'attività e gli eventi dell'host di virtualizzazione vengano monitorati in UTMStack.", + "NETFLOW": "Acquisisci i record NetFlow da router e switch per monitorare i pattern di traffico di rete e rilevare anomalie del traffico.", + "AWS_IAM_USER": "Acquisisci l'attività dell'account AWS e le chiamate API tramite CloudTrail e CloudWatch per controllare l'utilizzo cloud, gli accessi e le modifiche.", + "AZURE": "Acquisisci i log di piattaforma e attività di Microsoft Azure per monitorare i workload cloud, l'identità e le modifiche alle risorse.", + "O365": "Acquisisci i log di audit di Microsoft 365 su Exchange, Teams, SharePoint e OneDrive per monitorare l'attività degli utenti e degli amministratori.", + "O365_GRAPH": "Ingeste gli eventi di sicurezza di Microsoft Graph: allerte, incidenti, audit del directory, sign-in, rilevamenti di rischio e log di audit Purview per monitorare identità e attività di minaccia nel tuo tenant.", + "GCP": "Acquisisci i log di audit e attività di Google Cloud Platform per monitorare compute, storage e identità tra i progetti.", + "KASPERSKY": "Acquisisci i rilevamenti di Kaspersky Security Center e la telemetria degli endpoint per correlare l'attività malware nella rete.", + "ESET": "Acquisisci i rilevamenti endpoint e la telemetria di ESET PROTECT per correlare la difesa multilivello dal malware nel tuo parco macchine.", + "BITDEFENDER": "Acquisisci i rilevamenti di Bitdefender GravityZone e la telemetria degli endpoint per correlare le minacce tra i dispositivi aziendali.", + "SENTINEL_ONE": "Acquisisci i rilevamenti endpoint e la telemetria comportamentale di SentinelOne per correlare e investigare le minacce su larga scala.", + "SOPHOS": "Acquisisci i rilevamenti di Sophos Central su endpoint, server, firewall ed e-mail per correlare le minacce in un unico luogo.", + "CROWDSTRIKE": "Acquisisci i rilevamenti su endpoint e workload di CrowdStrike Falcon per correlare l'attività cloud-native delle minacce in UTMStack.", + "CISCO": "Acquisisci il traffico firewall Cisco ASA, VPN e log delle minacce per monitorare la sicurezza perimetrale e gli accessi in UTMStack.", + "MERAKI": "Acquisisci il syslog di firewall e security appliance Cisco Meraki per monitorare il traffico di rete e le minacce gestite nel cloud.", + "FIRE_POWER": "Acquisisci i log di Cisco Firepower NGFW e IPS per monitorare i tentativi di intrusione e l'attività delle minacce al perimetro.", + "CISCO_SWITCH": "Acquisisci il syslog e la telemetria degli switch Cisco per monitorare le prestazioni di rete, le modifiche alla configurazione e la sicurezza.", + "FORTIGATE": "Acquisisci il traffico Fortinet FortiGate NGFW e i log delle minacce per monitorare la sicurezza perimetrale e l'attività di rete.", + "FORTIWEB": "Acquisisci i log WAF di Fortinet FortiWeb per monitorare gli attacchi alle applicazioni web e proteggere servizi e API esposti.", + "SOPHOS_XG": "Acquisisci i log del firewall Sophos XG relativi a web filtering, IPS e VPN per monitorare il traffico di rete e le minacce.", + "PALO_ALTO": "Acquisisci il traffico Palo Alto Networks NGFW e i log delle minacce per monitorare l'utilizzo delle applicazioni e la sicurezza perimetrale.", + "SONIC_WALL": "Acquisisci il traffico SonicWall NGFW e i log delle minacce per monitorare la sicurezza perimetrale e l'attività di rete in UTMStack.", + "PFSENSE": "Acquisisci i log di firewall e router pfSense con unified threat management per monitorare il traffico di rete e le minacce.", + "MIKROTIK": "Acquisisci i log di firewall, routing e wireless di MikroTik RouterOS per monitorare l'attività di rete e la configurazione.", + "AIX": "Raccogli i log di sistema Unix IBM AIX, sicurezza e audit per monitorare l'attività sulle piattaforme IBM Power in UTMStack.", + "AS_400": "Raccogli journal di sistema e di controllo IBM AS/400 (IBM i) per monitorare l'attività degli utenti sulle piattaforme midrange OS/400.", + "ORACLE": "Acquisisci i log di audit di Oracle Database per monitorare query, accessi e attività privilegiate nei tuoi database.", + "SURICATA": "Acquisisci avvisi ed eventi di rete Suricata IDS/IPS per rilevare intrusioni e traffico malevolo sulla rete.", + "DECEPTIVE_BYTES": "Acquisisci gli avvisi di Deceptive Bytes dalla sua piattaforma di inganno attivo degli endpoint per rilevare tempestivamente l'attività degli attaccanti.", + "GITHUB": "Acquisisci i log di audit di GitHub per monitorare l'accesso ai repository, le modifiche al codice e l'attività dell'organizzazione ai fini della sicurezza del codice sorgente.", + "UTMSTACK": "Acquisisci la telemetria SIEM e XDR di UTMStack per monitorare l'integrità della piattaforma, l'attività interna e gli eventi di self-audit.", + "NGINX": { + "name": "Nginx", + "description": "Acquisisci i log di accesso ed errore di Nginx per monitorare l'attività del web server, il traffico del proxy inverso e le richieste dei client." + }, + "APACHE": { + "name": "Apache", + "description": "Acquisisci i log di accesso ed errore di Apache HTTPD per monitorare l'attività del web server e le richieste dei client." + }, + "APACHE2": { + "name": "Apache2", + "description": "Acquisisci i log del web server Apache2 (HTTPD) per monitorare la gestione delle richieste, gli errori e l'accesso sugli host Linux." + }, + "IIS": { + "name": "IIS", + "description": "Acquisisci l'attività di accesso e i file di log di Internet Information Services (IIS) per monitorare il web server di Windows." + }, + "MYSQL": { + "name": "MySQL", + "description": "Acquisisci l'attività di log di MySQL per monitorare query, autenticazione e accesso al data store." + }, + "POSTGRESQL": { + "name": "PostgreSQL", + "description": "Acquisisci i log di PostgreSQL per monitorare query, accesso e attività nei tuoi data store." + }, + "MONGODB": { + "name": "MongoDB", + "description": "Acquisisci l'attività di log di MongoDB per monitorare l'accesso al database documentale, le query e il comportamento dell'applicazione." + }, + "REDIS": { + "name": "Redis", + "description": "Acquisisci l'attività di log e telemetria di Redis per monitorare l'uso del data store in memoria e i workload in tempo reale." + }, + "ELASTICSEARCH": { + "name": "Elasticsearch", + "description": "Acquisisci i log di Elasticsearch per monitorare il motore di ricerca e analisi e i relativi workload applicativi." + }, + "LOGSTASH": { + "name": "Logstash", + "description": "Acquisisci i log delle pipeline Logstash per monitorare la pipeline di elaborazione dati e le trasformazioni degli eventi." + }, + "KIBANA": { + "name": "Kibana", + "description": "Acquisisci i log di Kibana per monitorare il layer di visualizzazione ed esplorazione dati e il relativo utilizzo." + }, + "KAFKA": { + "name": "Apache Kafka", + "description": "Acquisisci i log di Apache Kafka per monitorare le pipeline di streaming in tempo reale, i broker e il flusso dei messaggi." + }, + "NATS": { + "name": "NATS", + "description": "Acquisisci i log di messaging NATS per monitorare il message bus, la connettività e la consegna degli eventi." + }, + "HAPROXY": { + "name": "HAProxy", + "description": "Acquisisci i log di HAProxy per monitorare il bilanciamento del carico, il traffico del proxy e la disponibilità della rete." + }, + "TRAEFIK": { + "name": "Traefik", + "description": "Acquisisci i log di Traefik per monitorare il routing, il bilanciamento del carico e il traffico del proxy tra i workload." + }, + "OSQUERY": { + "name": "osquery", + "description": "Acquisisci i log di OsQuery per monitorare lo stato degli endpoint, le query e l'inventario di sistema tramite richieste in stile SQL." + }, + "SYSLOG": { + "name": "Syslog", + "description": "Invia syslog (RFC 5424/3164) da qualsiasi dispositivo o applicazione all'endpoint del collector per l'acquisizione centralizzata dei log." + }, + "JSON": { + "name": "JSON Input", + "description": "Invia carichi di log in JSON all'endpoint di acquisizione per l'ingest strutturata di eventi da applicazioni e script." + }, + "WINDOWS_SQL_SERVER": { + "name": "SQL Server Event Logs", + "description": "Collect Microsoft SQL Server audit and event records through the Windows Event Log and UTMStack agent." + }, + "WINDOWS_FILE_AUDITING": { + "name": "Windows File Access Auditing", + "description": "Collect Windows file access audit events through the Windows Event Log and UTMStack agent." + }, + "ELASTICsearch": { + "name": "ELASTICsearch", + "description": "Ingesta los registros de Elasticsearch para monitorear el motor de búsqueda y análisis y sus cargas de trabajo de aplicación." + } + }, + "edit": { + "title": "Modifica integrazione" + }, + "allCategories": "Tutte le categorie", + "customOnly": "Personalizzato" + }, + "dataProcessing": { + "title": "Elaborazione dati", + "subtitle": "Statistiche di ingestione ed elaborazione: eventi ricevuti, scartati per fase, e le principali origini e tipi.", + "ingestion": { + "title": "Ingestione", + "last24h": "ultime 24 ore", + "noData": "Nessun dato in questa finestra.", + "loadError": "Impossibile caricare le statistiche di ingestione.", + "groupBy": { + "dataSource": "Per origine dati", + "dataType": "Per tipo di dato" + }, + "status": { + "received": "Ricevuti", + "parsing_dropped": "Scartati (parsing)", + "analysis_dropped": "Scartati (analisi)", + "correlation_dropped": "Scartati (correlazione)", + "all": "Tutti gli eventi" + } + }, + "filters": { + "title": "Filtri", + "new": "Nuovo filtro", + "search": "Cerca per percorso…", + "refresh": "Aggiorna", + "retry": "Riprova", + "empty": "Nessun filtro corrisponde.", + "loadError": "Impossibile caricare i filtri.", + "toggleError": "Impossibile cambiare lo stato del filtro", + "system": "Sistema", + "custom": "Personalizzato", + "systemReadonly": "I filtri di sistema sono di sola lettura", + "view": "Visualizza", + "edit": "Modifica", + "ownership": { + "all": "Tutti", + "system": "Sistema", + "custom": "Personalizzati" + }, + "state": { + "all": "Tutti", + "active": "Attivi", + "inactive": "Inattivi" + }, + "col": { + "filter": "Filtro", + "type": "Tipo", + "active": "Attivo", + "actions": "Azioni" + }, + "pageInfo": "{{from}}–{{to}} di {{count}}" + }, + "editor": { + "createTitle": "Nuovo filtro", + "editTitle": "Modifica filtro", + "viewTitle": "Visualizza filtro", + "relPath": "Percorso", + "relPathHint": "Cartella + file, es. syslog/mio-filtro.yaml", + "content": "Pipeline (YAML)", + "contentHint": "I passaggi vengono eseguiti in ordine: grok, rename, delete, plugin dynamic, …", + "save": "Salva", + "saving": "Salvataggio…", + "saved": "Filtro salvato", + "saveError": "Impossibile salvare il filtro", + "cancel": "Annulla", + "delete": "Elimina", + "deleteConfirm": "Eliminare questo filtro?", + "deleted": "Filtro eliminato", + "deleteError": "Impossibile eliminare il filtro" + }, + "kpi": { + "received": "Ricevuti", + "dropped": "Scartati", + "dropRate": "{{rate}}% di scarto", + "stored": "Archiviati", + "throughput": "Throughput", + "perMin": "{{value}}/min", + "survival": "{{rate}}% mantenuti" + }, + "section": { + "overTime": "Eventi nel tempo", + "top": "Top", + "dropReasons": "Motivi di scarto" + }, + "live": { + "auto": "Auto" + }, + "pipeline": { + "title": "Pipeline di ingestione", + "stages": { + "received": "Ricevuti", + "parsed": "Analizzati (parse)", + "analyzed": "Analizzati", + "stored": "Archiviati" + } + }, + "chart": { + "title": "Throughput nel tempo", + "received": "Ricevuti", + "dropped": "Scartati" + }, + "donut": { + "title": "Composizione scarti", + "dropped": "scartati" + }, + "breakdown": { + "title": "Top sorgenti e tipi", + "bars": "Barre", + "treemap": "Treemap", + "showAll": "Mostra tutti i {{count}}", + "showLess": "Mostra meno", + "lastSeen": "Visto l’ultima volta", + "ago": "{{time}} fa" + } }, - "compliance": "Conformità", - "configure": "Configura", - "dataSources": "Origini dati", - "integrations": "Integrazioni", - "alertingRules": "Regole di avviso", - "dataProcessing": "Elaborazione dati", - "team": "Team", - "settings": "Impostazioni", - "back": "Indietro", - "regexPatterns": "Espressioni regolari", - "taggingRules": "Regole di etichettatura", - "parsingFilters": "Pipeline", - "overview": "Panoramica", - "tenants": "Tenant", - "openMenu": "Apri menu", - "closeMenu": "Chiudi menu", - "liveOps": "Operazioni live" - }, - "dashboards": { - "title": "Dashboard", - "subtitle": "Sfoglia e modifica dashboard interattive.", - "list": { - "title": "Dashboard", - "create": "Nuova", - "searchPlaceholder": "Cerca dashboard…", - "loading": "Caricamento delle dashboard…", - "empty": "Nessuna dashboard ancora.", - "rename": "Rinomina", - "delete": "Elimina" + "datasources": { + "limitBanner": { + "title": "Limite di datasource superato.", + "message": "Hai {{count}} datasource ma la tua licenza copre {{limit}}. I log dei datasource oltre il limite vengono scartati.", + "cta": "Gestisci licenza", + "dismiss": "Ignora" + }, + "title": "Origini dati", + "total": "{{count}} in totale", + "subtitle": "Agenti, integrazioni e origini dirette che inviano eventi. Lo stato è derivato dall'ultima volta che ogni origine è stata vista.", + "connectSource": "Collega un'origine", + "loading": "Caricamento origini dati…", + "loadFailed": "Impossibile caricare le origini dati.", + "retry": "Riprova", + "none": "Nessuna origine corrisponde a questa vista.", + "ingestion": { + "title": "Ingestione", + "received": "eventi ricevuti", + "none": "Nessuna ingestione nelle ultime 24 ore.", + "ago24h": "24h fa", + "now": "ora" + }, + "usage": { + "title": "Origini dati", + "ofUnlimited": "di illimitato", + "ofLimit": "di {{limit}}", + "overLimit": "Oltre il limite della licenza — i dati oltre il limite sono a rischio.", + "configured": "configurate" + }, + "tabs": { + "all": "Tutte", + "agent": "Agenti", + "puller": "Integrazioni", + "direct": "Dirette", + "offline": "Offline" + }, + "toolbar": { + "searchPlaceholder": "Cerca per nome…", + "list": "Elenco", + "cards": "Schede", + "refresh": "Aggiorna" + }, + "labels": { + "filteredBy": "Filtrato per label", + "add": "Aggiungi label…", + "addFirst": "Aggiungi un label…", + "hint": "Scrivi un label e premi Invio per aggiungerlo. Le modifiche vengono salvate automaticamente." + }, + "status": { + "live": "Attiva", + "idle": "Inattiva", + "offline": "Offline" + }, + "kind": { + "agent": "Agente", + "puller": "Integrazione", + "direct": "Diretta" + }, + "cols": { + "source": "Origine", + "type": "Tipo", + "status": "Stato", + "events24h": "Eventi 24h", + "lastSeen": "Vista l'ultima volta" + }, + "time": { + "justNow": "proprio ora", + "minutesAgo": "{{count}}m fa", + "hoursAgo": "{{count}}h fa", + "daysAgo": "{{count}}g fa" + }, + "drawer": { + "loading": "Caricamento…", + "loadFailed": "Impossibile caricare l'origine dati.", + "statsIdentity": "Statistiche e identità", + "metadata": "Metadati", + "labelsSection": "Labels", + "dangerZone": "Zona pericolosa", + "rows": { + "events24h": "Eventi 24h", + "lastSeen": "Vista l'ultima volta", + "discovered": "Scoperta", + "kind": "Tipo di origine", + "dataType": "Tipo di dato", + "ip": "IP", + "id": "ID" + }, + "dangerText": "L'eliminazione rimuove questa origine dal registro. Gli eventi storici restano consultabili nel Log Explorer; se l'origine continua a inviare dati, verrà riscoperta.", + "delete": "Elimina origine", + "confirmDelete": "Conferma eliminazione", + "cancel": "Annulla", + "viewLogs": "Visualizza log", + "trend": "Andamento ingestione", + "noTrend": "Nessun evento ricevuto in questo intervallo", + "logGap": "Ultimo evento {{since}} — possibile interruzione dei log" + }, + "toast": { + "labelsUpdated": "Labels aggiornati", + "labelsFailed": "Impossibile aggiornare i labels", + "deleted": "Origine eliminata", + "deleteFailed": "Eliminazione non riuscita" + }, + "sensitivity": { + "section": "Sensibilità dell'asset", + "hint": "Criticità di business (CIA, 0–3) di questo asset. Gli alert diretti al suo host/IP sono pesati con questi valori.", + "saved": "Sensibilità aggiornata", + "failed": "Aggiornamento della sensibilità non riuscito", + "save": "Salva", + "confidentiality": "Riservatezza", + "integrity": "Integrità", + "availability": "Disponibilità", + "levels": { + "0": "Nessuna", + "1": "Bassa", + "2": "Media", + "3": "Alta" + } + }, + "console": { + "section": "Console", + "sectionHint": "Esegui comandi su questo host tramite il suo agente (risposta in tempo reale).", + "open": "Apri console", + "close": "Chiudi", + "hint": "Digita un comando e premi Invio per eseguirlo sull'agente.", + "running": "Esecuzione in corso…", + "placeholder": "Digita un comando…", + "offline": "Questo agente sembra offline — potrebbe non rispondere ai comandi.", + "vars": { + "button": "Variabili", + "title": "Variabili dei comandi", + "subtitle": "Richiamale nei comandi come", + "add": "Nuova variabile", + "name": "Nome", + "value": "Valore", + "description": "Descrizione", + "isSecret": "Segreto (cifrato, mascherato nell'output)", + "secret": "segreto", + "secretHint": "Lascia vuoto per mantenere il valore memorizzato.", + "save": "Salva", + "cancel": "Annulla", + "edit": "Modifica", + "delete": "Elimina", + "loading": "Caricamento in corso…", + "empty": "Nessuna variabile.", + "saved": "Variabile salvata", + "deleted": "Variabile eliminata", + "nameRequired": "Il nome è obbligatorio", + "loadError": "Impossibile caricare le variabili", + "saveError": "Impossibile salvare la variabile", + "deleteError": "Impossibile eliminare la variabile", + "insert": "Inserisci", + "valueRequired": "Il valore è obbligatorio" + }, + "disabled": "Agente offline — i comandi sono disabilitati", + "connError": "Errore di connessione", + "cmdError": "Errore del comando", + "shellSelect": "Tipo di shell", + "noRemoteControl": "Questo agente è stato installato con il controllo remoto disattivato. Rifiuta i comandi, e questo si può cambiare solo sulla macchina stessa.", + "noRemoteControlShort": "Controllo remoto disattivato su questo agente", + "password": { + "title": "Autenticazione", + "hint": "Autenticarsi per eseguire comandi su questo agente.", + "tfaPrompt": "Codice: ", + "confirm": "OK", + "cancel": "Annulla", + "authError": "Autenticazione non riuscita", + "authHint": "Autenticarsi per eseguire comandi su questo agente.", + "authOk": "Autenticato." + } + }, + "health": { + "online": "online", + "offline": "offline", + "total": "totale" + } }, - "actions": { - "edit": "Modifica", - "editWithAi": "Modifica con l'IA" + "adversaries": { + "title": "Vista avversari", + "subtitle": "Ogni IP, host o utente visto attaccare il tuo ambiente, con tecniche e obiettivi.", + "countChip": "{{count}} avversari", + "refresh": "Aggiorna", + "search": "Cerca per IP, host, utente, paese, ASO…", + "empty": "Nessun avversario corrisponde.", + "loadError": "Impossibile caricare gli avversari.", + "retry": "Riprova", + "views": { + "all": "Tutti", + "high": "Severità alta", + "ip": "IP", + "host": "Host", + "user": "Utenti" + }, + "threat": { + "critical": "Critico", + "high": "Alto", + "medium": "Medio", + "low": "Basso" + }, + "kind": { + "ip": "IP", + "host": "Host", + "user": "Utente" + }, + "layout": { + "list": "Elenco", + "cards": "Schede" + }, + "overview": { + "title": "Attività degli avversari · ultime 24 ore", + "high": "severità alta", + "countries": "paesi", + "alerts": "avvisi", + "ago24": "24h fa", + "ago12": "12h fa", + "now": "ora" + }, + "col": { + "adversary": "Avversario", + "threat": "Minaccia", + "alerts": "Avvisi", + "targets": "Obiettivi", + "lastSeen": "Visto l’ultima volta", + "victims": "Vittime" + }, + "card": { + "alerts": "Avvisi", + "techniques": "Tecniche", + "targets": "Obiettivi" + }, + "tabs": { + "profile": "Profilo", + "techniques": "Tecniche", + "targets": "Obiettivi", + "alerts": "Avvisi" + }, + "drawer": { + "activity": "Attività in 24 ore", + "identification": "Identificazione", + "kindLabel": "Tipo", + "identifier": "Identificatore", + "firstSeen": "Visto la prima volta", + "lastSeen": "Visto l’ultima volta", + "geolocation": "Geolocalizzazione", + "country": "Paese", + "city": "Città", + "topTechniques": "Tecniche principali", + "noTechniques": "Nessuna tecnica registrata.", + "targets": "Obiettivi", + "noTargets": "Nessun obiettivo registrato.", + "recentAlerts": "Avvisi recenti", + "noAlerts": "Nessun avviso.", + "echoes": "{{count}} ripetizioni" + }, + "relative": { + "justNow": "proprio ora", + "minutesAgo": "{{count}}m fa", + "hoursAgo": "{{count}}h fa", + "daysAgo": "{{count}}g fa" + }, + "field": { + "ip": "IP", + "host": "Host", + "user": "Utente", + "port": "Porta", + "domain": "Dominio", + "mac": "MAC", + "country": "Paese", + "city": "Città", + "asn": "ASN", + "aso": "ASO" + } }, - "refresh": { - "title": "Aggiornamento automatico", - "options": { - "off": "Disattivato", - "10s": "10s", - "30s": "30s", - "1m": "1m", - "5m": "5m", - "15m": "15m" - } + "timeRange": { + "quick": "Intervalli rapidi", + "relative": "Relativo", + "absolute": "Assoluto", + "last": "Ultimi", + "apply": "Applica", + "allTime": "Tutto il tempo", + "from": "Da", + "to": "A", + "now": "adesso", + "units": { + "minutes": "minuti", + "hours": "ore", + "days": "giorni", + "weeks": "settimane", + "months": "mesi" + }, + "presets": { + "15m": "Ultimi 15 minuti", + "1h": "Ultima ora", + "6h": "Ultime 6 ore", + "24h": "Ultime 24 ore", + "7d": "Ultimi 7 giorni", + "30d": "Ultimi 30 giorni" + } }, - "editor": { - "editing": "In modifica", - "addWidget": "Aggiungi widget", - "save": "Salva", - "discard": "Annulla", - "newTitle": "Nuovo widget", - "newSubtitle": "Scegli un tipo di grafico, una fonte di dati e modellalo visivamente. L'SQL viene generato automaticamente.", - "editTitle": "Modifica widget", - "editSubtitle": "Modifica la definizione del grafico. Le modifiche si applicano ovunque questo widget sia usato.", - "loading": "Caricamento del widget…", - "notFoundTitle": "Widget non trovato", - "notFoundSubtitle": "Potrebbe essere stata eliminata oppure non hai i permessi per accedervi.", - "backToDashboard": "Torna alla dashboard", - "chartType": { - "title": "Tipo di grafico" - }, - "chartTypes": { - "bar": { - "label": "Barre", - "description": "Confronta valori tra categorie." - }, - "line": { - "label": "Linea", - "description": "Tendenze lungo un asse ordinato." - }, - "area": { - "label": "Area", - "description": "Linea riempita — enfatizza il volume." - }, - "pie": { - "label": "Torta", - "description": "Quota sul totale per categoria." - }, - "metric": { - "label": "Metrica", - "description": "Un singolo valore scalare." + "alerts": { + "title": "Avvisi", + "matching": "{{count}} corrispondenti", + "subtitle": "Dai priorità a ciò che conta.", + "openNow": "aperti in questo momento.", + "view": { + "alerts": "Avvisi", + "overview": "Panoramica" + }, + "toolbar": { + "searchPlaceholder": "Cerca per nome dell'avviso…", + "allSeverities": "Tutte le gravità", + "export": "Esporta CSV", + "refresh": "Aggiorna" + }, + "severity": { + "high": "Alta", + "medium": "Media", + "low": "Bassa" + }, + "status": { + "open": "Aperto", + "in_review": "In revisione", + "completed": "Completato", + "auto": "Revisione automatica" + }, + "statusTabs": { + "all": "Tutti" + }, + "overview": { + "overTime": "Avvisi nel tempo", + "matchingAlerts": "avvisi corrispondenti", + "noData": "Nessun dato.", + "bySeverity": "Per gravità", + "byStatus": "Per stato" + }, + "filters": { + "add": "Aggiungi filtro", + "clearAll": "Cancella tutto", + "filterValues": "Filtra valori…", + "loadingValues": "Caricamento valori…", + "noValues": "Nessun valore trovato.", + "pickValue": "Scegli un valore per aggiungere il filtro.", + "empty": "(vuoto)", + "cancel": "Annulla", + "addBtn": "Aggiungi" + }, + "ops": { + "CONTAIN": "contiene", + "IS": "è", + "IS_NOT": "non è", + "EXIST": "esiste", + "DOES_NOT_EXIST": "non esiste" + }, + "fields": { + "adversary_domain": "Dominio dell'avversario", + "adversary_geolocation_asn": "ASN dell'avversario", + "adversary_geolocation_aso": "ASO dell'avversario", + "adversary_geolocation_country": "Paese dell'avversario", + "adversary_host": "Host dell'avversario", + "adversary_ip": "IP dell'avversario", + "adversary_url": "URL dell'avversario", + "adversary_user": "Utente dell'avversario", + "assignee": "Assegnato a", + "category": "Categoria", + "dataSource": "Sensore", + "dataType": "Tipo di dato", + "description": "Descrizione", + "id": "ID", + "impactScore": "Rischio", + "impact_availability": "Disponibilità", + "impact_confidentiality": "Riservatezza", + "impact_integrity": "Integrità", + "incidentDetail_incidentName": "Nome dell'incidente", + "incidentDetail_incidentId": "Id incidente", + "isIncident": "È un incidente", + "name": "Nome dell'avviso", + "notes": "Note", + "severity": "Gravità", + "status": "Stato", + "tags": "Tag", + "target_domain": "Dominio dell'obiettivo", + "target_geolocation_asn": "ASN dell'obiettivo", + "target_geolocation_aso": "ASO dell'obiettivo", + "target_geolocation_country": "Paese dell'obiettivo", + "target_host": "Host dell'obiettivo", + "target_ip": "IP dell'obiettivo", + "target_url": "URL dell'obiettivo", + "target_user": "Utente dell'obiettivo", + "technique": "Tecnica" + }, + "tagFilter": { + "tags": "Tag", + "tag_one": "{{count}} tag", + "tag_other": "{{count}} tag", + "clearSelection": "Cancella selezione", + "noTags": "Nessun tag" + }, + "bulk": { + "selected": "{{count}} selezionati", + "setStatus": "Imposta stato", + "addTag": "Aggiungi tag", + "noTags": "Nessun tag", + "addToIncident": "Aggiungi a incidente", + "clear": "Cancella" + }, + "tagEditor": { + "tag": "Tag", + "noTagsYet": "Ancora nessun tag", + "createTag": "Crea tag", + "newTagName": "Nome del nuovo tag…", + "createApply": "Crea e applica tag", + "save": "Salva", + "cancel": "Annulla", + "edit": "Modifica tag", + "delete": "Elimina tag", + "systemLocked": "Tag di sistema (bloccato)", + "alreadyExists": "Questo tag esiste già.", + "color": "Colore {{color}}", + "createRule": "Crea una regola di etichettatura con questa etichetta" }, "table": { - "label": "Tabella", - "description": "Righe aggregate." + "actions": "Azioni", + "alert": "Avviso", + "status": "Stato", + "technique": "Tecnica", + "severity": "Gravità", + "risk": "Rischio", + "echoes": "Echi", + "time": "Ora", + "riskHint": "Punteggio di rischio (0–100), colorato in base alla gravità", + "source": "Origine", + "adversary": "Avversario" + }, + "row": { + "createRuleFromAlert": "Crea un'etichetta da questo avviso", + "createIncident": "Crea un incidente da questo avviso", + "viewIncident": "Vedi dettagli dell'incidente", + "assignedTo": "Assegnato a {{user}}", + "echoesTooltip": "{{count}} echi — clicca per espandere", + "echoesEmpty": "Nessun eco registrato" + }, + "echoes": { + "title": "{{count}} echi", + "close": "Chiudi", + "empty": "Nessun eco registrato per questo avviso.", + "loadError": "Impossibile caricare gli echi." }, "list": { - "label": "Elenco", - "description": "Righe grezze, non aggregate." + "loading": "Caricamento avvisi…", + "loadError": "Impossibile caricare gli avvisi.", + "retry": "Riprova", + "empty": "Nessun avviso corrisponde a questa vista." }, - "region_map": { - "label": "Mappa di coordinate", - "description": "Posiziona indicatori su un planisfero usando coordinate lat/lon." + "badge": { + "incident": "Incidente", + "aiAssessed": "Valutato dall’IA" }, - "text": { - "label": "Testo", - "description": "Testo libero o semplice output per riga." + "drawer": { + "setStatus": "Imposta stato", + "completeFalsePositive": "Completa + falso positivo", + "addToIncident": "Aggiungi a incidente", + "partOfIncident": "Parte di un incidente", + "tabs": { + "summary": "Riepilogo", + "parties": "Parti", + "events": "Eventi", + "history": "Cronologia" + }, + "section": { + "description": "Descrizione", + "solution": "Soluzione", + "references": "Riferimenti", + "details": "Dettagli", + "yourNotes": "Le tue note", + "notes": "Note" + }, + "details": { + "severity": "Gravità", + "risk": "Rischio", + "category": "Categoria", + "technique": "Tecnica", + "sensor": "Sensore", + "dataType": "Tipo di dato", + "alertId": "ID avviso", + "statusNote": "Nota di stato", + "assignee": "Assegnatario" + }, + "incidentDetail": { + "incident": "Incidente", + "id": "ID", + "createdBy": "Creato da", + "created": "Creato" + }, + "notesPlaceholder": "Aggiungi note di indagine…", + "saveNotes": "Salva note", + "assignee": "Assegna", + "assign": "Assegna", + "unassign": "Rimuovi assegnazione", + "unassigned": "Non assegnato", + "loadingUsers": "Caricamento utenti…", + "observationLabel": "Osservazione", + "observationPlaceholder": "Aggiungi un'osservazione…", + "cancel": "Annulla", + "continue": "Continua" + }, + "related": { + "sample": "Un campione fino a ~11 eventi che il motore ha memorizzato su questo avviso. Usa «Vedi tutti i log correlati» per l’insieme completo e senza limiti.", + "loadingEchoes": "Caricamento degli eventi dei suoi echi…", + "sampleWithEchoes": "Gli eventi memorizzati su questo avviso e sui suoi {{count}} echi ({{read}} letti). Usa «Vedi tutti i log correlati» per l’insieme completo e senza limiti.", + "empty": "Nessun evento di campione memorizzato su questo avviso. Carica l’insieme correlato completo nell’Esploratore log.", + "viewAll": "Vedi tutti i log correlati" + }, + "party": { + "source": "Origine / obiettivo", + "adversary": "Avversario", + "noData": "Nessun dato.", + "ip": "IP", + "host": "Host", + "user": "Utente", + "domain": "Dominio", + "country": "Paese" + }, + "history": { + "empty": "Nessuna cronologia registrata.", + "by": "da {{user}}", + "actions": { + "UPDATE_STATUS": "Stato aggiornato", + "UPDATE_TAGS": "Tag aggiornati", + "UPDATE_NOTES": "Note aggiornate", + "UPDATE_SOLUTION": "Soluzione aggiornata", + "MARK_AS_INCIDENT": "Contrassegnato come incidente" + }, + "detail": { + "statusTo": "Stato → {{status}}", + "tags": "Tag: {{tags}}", + "aiAdded": "Valutazione IA aggiunta", + "observationAdded": "Osservazione aggiunta", + "notesUpdated": "Note aggiornate" + } + }, + "ai": { + "title": "Valutazione IA del SOC", + "risk": "rischio {{risk}}", + "score": "{{score}}/100", + "generate": "Genera riepilogo IA", + "hint": "SOC-AI analizza questo avviso e aggiunge una valutazione.", + "generating": "Analisi dell'avviso in corso… può richiedere un minuto.", + "ready": "Riepilogo IA pronto", + "failed": "Impossibile generare il riepilogo IA", + "slow": "Il riepilogo IA sta impiegando più tempo del previsto. Comparirà sull'avviso quando sarà pronto." + }, + "incident": { + "titleAdd_one": "Aggiungi {{count}} avviso a un incidente", + "titleAdd_other": "Aggiungi {{count}} avvisi a un incidente", + "new": "Nuovo incidente", + "existing": "Incidente esistente", + "nameLabel": "Nome dell'incidente", + "namePlaceholder": "es. Sospetta intrusione di Scattered Spider", + "descriptionLabel": "Descrizione", + "descriptionPlaceholder": "Riepilogo facoltativo…", + "pickLabel": "Scegli un incidente", + "loading": "Caricamento…", + "selectPlaceholder": "Seleziona un incidente…", + "willLink_one": "{{count}} avviso sarà collegato.", + "willLink_other": "{{count}} avvisi saranno collegati.", + "cancel": "Annulla", + "create": "Crea incidente", + "add": "Aggiungi a incidente" + }, + "toast": { + "statusUpdated": "Stato aggiornato", + "statusFailed": "Impossibile aggiornare lo stato", + "tagsUpdated": "Tag aggiornati", + "tagsFailed": "Impossibile aggiornare i tag", + "tagCreateFailed": "Impossibile creare il tag", + "tagUpdated": "Tag aggiornato", + "tagUpdateFailed": "Impossibile aggiornare il tag", + "tagDeleted": "Tag eliminato", + "tagDeleteFailed": "Impossibile eliminare il tag", + "notesSaved": "Note salvate", + "notesFailed": "Impossibile salvare le note", + "exportFailed": "Impossibile esportare il CSV", + "noRelatedLogs": "Nessun log correlato trovato per questo avviso", + "relatedLogsFailed": "Impossibile caricare i log correlati", + "incidentCreated": "Incidente creato", + "alertsAdded": "Avvisi aggiunti all’incidente", + "incidentFailed": "Impossibile salvare l’incidente", + "assigned": "Alert assegnato", + "unassigned": "Assegnazione dell'alert rimossa", + "assignFailed": "Impossibile aggiornare l'assegnatario", + "newAlertsToast_title": "Nuovi alert", + "newAlertsToast_count_one": "{{count}} nuovo alert", + "newAlertsToast_count_other": "{{count}} nuovi alert", + "newAlertsToast_view": "Visualizza" } - }, - "dataSource": { - "title": "Quali dati?", - "dataset": "Set di dati", - "noDatasetHint": "Scegli un set di dati per abilitare condizioni e raggruppamento." - }, - "widgetTitle": { - "label": "Titolo", - "placeholder": "Facoltativo — predefinito il tipo di grafico" - }, - "dataset": { - "placeholder": "Seleziona un set di dati…", - "loading": "Caricamento dei set di dati…" - }, - "filters": { - "title": "Includi solo eventi in cui…", - "empty": "Nessuna condizione: vengono inclusi tutti gli eventi dell’intervallo di tempo.", - "add": "Aggiungi condizione", - "remove": "Rimuovi", - "field": "Campo", - "fieldPlaceholder": "es. host.name", - "operator": "Operatore", - "value": "Valore", - "valuePlaceholder": "Valore", - "from": "Da", - "to": "A", - "noValue": "Nessun valore richiesto", - "listPlaceholder": "Valori separati da virgola" - }, - "operators": { - "IS": "è", - "IS_NOT": "non è", - "IS_ONE_OF_TERMS": "è uno tra", - "IS_GREATER_THAN": "è maggiore di", - "IS_LESS_THAN_OR_EQUALS": "è minore o uguale a", - "IS_BETWEEN": "è compreso tra", - "CONTAIN": "contiene", - "DOES_NOT_CONTAIN": "non contiene", - "START_WITH": "inizia con", - "ENDS_WITH": "termina con", - "EXIST": "esiste", - "DOES_NOT_EXIST": "non esiste" - }, - "dimension": { - "title": "Raggruppa per", - "field": "Campo", - "placeholder": "Scegli un campo per raggruppare…" - }, - "table": { - "hint": "Mostra tutti i campi dei record. Aggiungi colonne per sceglierne alcune.", - "columnsTitle": "Colonne", - "allColumns": "Verranno mostrate tutte le colonne. Aggiungi campi per sceglierne di specifiche.", - "addColumn": "Aggiungi una colonna…", - "removeColumn": "Rimuovi colonna" - }, - "chartPreview": { - "title": "Anteprima del grafico", - "noQuery": "Scegli un set di dati per vedere l’anteprima.", - "error": "La query di anteprima non è andata a buon fine." - }, - "chartTypeChip": { - "label": "Grafico:" - }, - "chartTypeModal": { - "title": "Scegli un tipo di grafico", - "subtitle": "Scegli come visualizzare i dati. Potrai cambiarlo in seguito.", - "confirm": "Continua", - "swapTitle": "Cambia tipo di grafico", - "swapConfirm": "Applica" - }, - "saveVisualization": "Salva widget", - "fieldSelect": { - "loading": "Caricamento dei campi…", - "choose": "Scegli un campo…" - }, - "toast": { - "notReady": "Scegli un set di dati e un campo per la suddivisione prima di salvare." - }, - "breakdown": { - "title": "Suddividi per", - "topValuesTable": "Tabella dei valori principali", - "time": "Nel tempo", - "field": "Valori più frequenti", - "interval": "Dimensione dell'intervallo", - "intervalAuto": "Automatico", - "limit": "Quanti", - "limitPlaceholder": "Predefinito (50)", - "splitHint": "Facoltativo: una linea per ogni valore di questo campo." - }, - "editFilters": "Edit filters" - }, - "grid": { - "empty": "Questa dashboard non ha ancora widget.", - "missingVisualization": "Widget non disponibile", - "unknownVisualization": "Widget" - }, - "widget": { - "renderError": "Impossibile renderizzare questo widget.", - "count": "Conteggio", - "loading": "Caricamento dei dati…", - "queryError": "Impossibile caricare i dati del widget.", - "noData": "Nessun dato per l'intervallo di tempo selezionato.", - "regionMapEmpty": "Nessun punto con lat/lon validi.", - "regionMapShapeHint": "L'SQL deve restituire le colonne di latitudine e longitudine (oppure un array value [lat, lon, count]).", - "regionMapUnnamed": "(senza nome)", - "regionMapValue": "valore: {{value}}", - "editAriaLabel": "Modifica widget", - "removeAriaLabel": "Rimuovi widget", - "moveBack": "Sposta indietro", - "moveForward": "Sposta avanti", - "width": "Larghezza", - "height": "Altezza", - "widthSmall": "1 col", - "widthMedium": "2 col", - "widthLarge": "3 col", - "heightNormal": "Normale", - "heightTall": "Alta", - "incompleteSpec": "A questo widget manca una parte della domanda." - }, - "form": { - "createTitle": "Nuova dashboard", - "renameTitle": "Modifica dashboard", - "name": "Nome", - "namePlaceholder": "es. Panoramica di rete", - "description": "Descrizione", - "descriptionPlaceholder": "Facoltativo", - "cancel": "Annulla", - "create": "Crea", - "save": "Salva" - }, - "confirm": { - "deleteTitle": "Elimina dashboard", - "delete": "Eliminare la dashboard «{{name}}»? Questa azione è irreversibile.", - "deleteWidgetsTitle": "Elimina widget", - "deleteWidgets_one": "Eliminare questo widget? Questa azione è irreversibile.", - "deleteWidgets_other": "Eliminare {{count}} widget? Questa azione è irreversibile.", - "dismissTitle": "Rimuovi dashboard", - "dismiss": "Rimuovere la dashboard predefinita \"{{name}}\"? Potrai crearne una nuova a partire da questa con \"Nuova\" → \"Da una esistente\"." - }, - "page": { - "noSelection": "Scegli una dashboard dall'elenco, oppure creane una per iniziare.", - "loading": "Caricamento dei widget…" - }, - "toast": { - "created": "Dashboard creata.", - "createFailed": "Impossibile creare la dashboard.", - "updated": "Dashboard aggiornata.", - "updateFailed": "Impossibile aggiornare la dashboard.", - "deleted": "Dashboard eliminata.", - "deleteFailed": "Impossibile eliminare la dashboard.", - "layoutSaved": "Layout salvato.", - "layoutSaveFailed": "Impossibile salvare il layout.", - "visualizationCreated": "Widget creato.", - "visualizationCreateFailed": "Impossibile creare il widget.", - "visualizationUpdated": "Widget aggiornato.", - "visualizationUpdateFailed": "Impossibile aggiornare il widget.", - "visualizationDeleted": "Widget eliminato.", - "visualizationDeleteFailed": "Impossibile eliminare il widget.", - "filterCreated": "Filtro creato.", - "filterUpdated": "Filtro aggiornato.", - "filterDeleted": "Filtro eliminato.", - "filterCreateFailed": "Impossibile creare il filtro.", - "filterUpdateFailed": "Impossibile aggiornare il filtro.", - "filterDeleteFailed": "Impossibile eliminare il filtro.", - "filtersSaved": "Filters saved.", - "filtersSaveFailed": "Could not save filters." }, - "newDashboard": { - "title": "Nuova dashboard", - "subtitle": "Crea una dashboard vuota. Potrai aggiungere widget dopo averla salvata.", - "modeManual": "Crea manualmente", - "modeAi": "Con l'IA", - "aiLocked": "Attiva SOC-AI e configuralo per usare questa funzione.", - "aiDescriptionLabel": "Cosa deve mostrare questa dashboard?", - "aiDescriptionPlaceholder": "es. Accessi falliti per paese, ultimi 7 giorni", - "aiCreate": "Crea con l'IA", - "aiOpenerWithDetails": "Crea una dashboard chiamata \"{{name}}\" che mostri: {{description}}" - }, - "newVisualization": { - "title": "Nuovo widget", - "subtitle": "Definisci un grafico riutilizzabile partendo da una query SQL e da una configurazione ECharts.", - "sqlQuery": "Query SQL", - "sqlQueryPlaceholder": "SELECT bucket, count(*) FROM logs GROUP BY bucket", - "sqlQueryHint": "Usa i segnaposto timeFilter, from e to (tra doppie parentesi graffe) per applicare il selettore temporale al rendering.", - "config": "Configurazione del grafico (opzione ECharts, JSON)", - "configHint": "Deve essere un JSON valido. Le righe dell'SQL sono esposte come `dataset.source` — collega le tue serie con `encode`.", - "configError": "JSON non valido: {{error}}" - }, - "visualizationList": { - "title": "Widget", - "subtitle": "{{count}} widget disponibili.", - "subtitleFiltered": "Visualizzate {{shown}} su {{total}}.", - "create": "Nuova", - "searchPlaceholder": "Cerca widget…", - "loading": "Caricamento dei widget…", - "empty": "Nessun widget ancora.", - "emptyFiltered": "Nessun widget corrisponde ai filtri attuali.", - "delete": "Elimina", - "deleteTitle": "Elimina widget", - "confirmDelete": "Eliminare il widget «{{name}}»? Questa azione è irreversibile.", - "filters": { - "search": "Cerca", - "chartType": "Tipo di grafico", - "allChartTypes": "Tutti i tipi di grafico", - "source": "Fonte", - "allSources": "Tutte le fonti", - "createdAt": "Creata", - "modifiedAt": "Modificata", - "createdRangeTitle": "Intervallo personalizzato — Creazione", - "modifiedRangeTitle": "Intervallo personalizzato — Modifica", - "pickRange": "Scegli un intervallo", - "datePresets": { - "all": "Tutti i periodi", - "today": "Oggi", - "last7": "Ultimi 7 giorni", - "last30": "Ultimi 30 giorni", - "lastYear": "Ultimo anno", - "custom": "Intervallo personalizzato" - }, - "clear": "Cancella filtri" - }, - "col": { - "name": "Nome", - "chartType": "Tipo di grafico", - "source": "Fonte", - "description": "Descrizione", - "created": "Creata", - "modified": "Modificata" - } - }, - "tabs": { - "dashboards": "Dashboard", - "visualizations": "Widget", - "newDashboard": "Nuova dashboard", - "unsetDefault": "Rimuovi predefinita", - "options": "Opzioni" - }, - "picker": { - "none": "Seleziona dashboard", - "search": "Cerca dashboard…", - "new": "Nuova dashboard", - "setDefault": "Imposta come predefinita", - "empty": "Nessuna dashboard" - }, - "empty": { - "title": "Ancora nessuna dashboard", - "body": "Crea la tua prima dashboard per vedere i tuoi dati di sicurezza a colpo d’occhio.", - "cta": "Crea dashboard" - }, - "filters": { - "addTitle": "Aggiungi filtro", - "editTitle": "Modifica filtro", - "removeTitle": "Rimuovi filtro", - "removeConfirm": "Rimuovere il filtro \"{{label}}\"? Questa azione è irreversibile.", - "remove": "Rimuovi", - "editAria": "Modifica filtro", - "removeAria": "Rimuovi filtro", - "saving": "Salvataggio…", - "addChip": "Aggiungi filtro", - "chooseValue": "Choose…", - "selected": "selected", - "loading": "Loading values…", - "searchPlaceholder": "Search values…", - "noValues": "No values available.", - "loadError": "Could not load values.", - "clear": "Clear", - "editorTitle": "Dashboard filters", - "editorHint": "Add dropdown chips that filter every widget on this dashboard.", - "emptyEditor": "No filter chips yet. Add one to get started.", - "cancel": "Cancel", - "save": "Save", - "field": { - "dataset": "Data set", - "field": "Field", - "chooseField": "Choose a field…", - "label": "Label", - "labelPlaceholder": "e.g. Host", - "placeholder": "Placeholder", - "placeholderPlaceholder": "e.g. Pick a host", - "multiple": "Multiple", - "searchable": "Searchable" - } - }, - "duplicate": { - "copyName": "{{name}} (copia)" - } - }, - "settings": { - "title": "Impostazioni", - "license": "Licenza", - "notifications": "Notifiche", - "connectionKey": "Chiave di connessione", - "dataRetention": "Conservazione dati", - "indices": "Indici", - "theme": "Tema", - "branding": "Brand", - "apiKeys": "Chiavi API", - "identityProviders": "Provider di identità", - "email": "Configurazione email", - "dateFormat": "Formato data", - "language": "Lingua", - "auditLogs": "Log di audit", - "about": "Informazioni", - "socAi": "SOC-AI", - "supportAccess": "Accesso di supporto", - "threatwinds": "Integrazione ThreatWinds" - }, - "topbar": { - "theme": { - "light": "Modalità chiara", - "dark": "Modalità scura" - }, - "manageLicense": "Gestisci licenza", - "profile": { - "profile": "Profilo", - "license": "Licenza", - "logout": "Esci" - } - }, - "notifications": { - "title": "Notifiche", - "markAllRead": "Segna tutte come lette", - "empty": "Non hai notifiche.", - "viewAll": "Vedi tutte", - "markRead": "Segna come letta", - "markUnread": "Segna come non letta", - "delete": "Elimina", - "subtitle": "{{total}} in totale · {{unread}} non lette", - "allCaughtUp": "Tutto in ordine.", - "loadFailed": "Impossibile caricare le notifiche." - }, - "pagination": { - "perPage": "Per pagina", - "pageOf": "Pagina {{page}} di {{total}}", - "previous": "Precedente", - "next": "Successiva" - }, - "license": { - "title": "Licenza", - "subtitle": "La tua edizione, funzionalità e file di licenza.", - "loading": "Caricamento licenza…", - "loadError": "Impossibile caricare le informazioni sulla licenza.", - "statusLabel": "Stato", - "status": { - "community": "Community", - "active": "Attiva", - "expiring": "In scadenza", - "expired": "Scaduta" - }, - "edition": "Edizione", - "enterprise": "Enterprise", - "community": "Community", - "editionLine": "Edizione {{edition}}", - "datasourceLimit": "Limite origini dati", - "unlimited": "Illimitato", - "mssp": "MSSP / multi-tenant", - "enabled": "Attivato", - "licenseType": "Tipo di licenza", - "instanceId": "ID istanza", - "enterpriseUnlocked": "Funzionalità Enterprise sbloccate", - "validUntil": "Valida fino al", - "noExpiry": "Nessuna scadenza", - "timeRemaining": "Tempo rimanente", - "expiredAgo": "Scaduta {{days}}g fa", - "daysShort": "{{days}}g", - "msspShort": "MSSP", - "communityEdition": "Edizione Community", - "communityBlurb": "Gratuita e open source. Carica una licenza Enterprise qui sotto per sbloccare multi-tenancy, SSO, limiti di origini dati più elevati e conformità avanzata.", - "upgrade": "Passa a Enterprise", - "uploadTitle": "Carica una licenza", - "uploadBlurb": "Installa o sostituisci il file LICENSE firmato. Il server verifica firma e scadenza prima di applicarlo. Solo admin.", - "installLicense": "Installa licenza", - "chooseFile": "Scegli file", - "noFileSelected": "Nessun file selezionato", - "toast": { - "installed": "Licenza installata — edizione {{edition}}.", - "adminRequired": "Sono richiesti privilegi di amministratore per caricare una licenza.", - "invalid": "File di licenza non valido o scaduto.", - "installFailed": "Impossibile installare la licenza." - }, - "ingestLimit": "Volume di ingest", - "notMetered": "Non misurato", - "gbPerMonth": "{{gb}} GB/mese" - }, - "audit": { - "title": "Log di audit", - "subtitle": "Registro di ogni azione rilevante per la sicurezza.", - "totalEntries": "{{total}} voci in totale.", - "loadError": "Impossibile caricare il log di audit", - "stats": { - "totalEntries": "Voci totali", - "acrossAllTime": "Di tutto il periodo", - "successRate": "Tasso di successo", - "failuresOnPage_one": "{{count}} errore in questa pagina", - "failuresOnPage_other": "{{count}} errori in questa pagina", - "topAction": "Azione principale", - "onPage": "{{count}} in questa pagina", - "uniqueActors": "Attori unici", - "includingSystem": "Incluso il sistema" - }, - "filters": { - "title": "Filtri", - "clear": "Cancella", - "last24h": "Ultime 24h", - "failuresOnly": "Solo errori", - "authEvents": "Eventi di autenticazione", - "actionPrefix": "Prefisso azione", - "actionPlaceholder": "es. auth., user.update", - "status": "Stato", - "any": "Qualsiasi", - "resourceType": "Tipo di risorsa", - "resourceTypePlaceholder": "user, alert…", - "resourceId": "ID risorsa", - "user": "Utente", - "userPlaceholder": "login…" - }, - "statusValue": { - "success": "Successo", - "failure": "Errore" - }, - "table": { - "timestamp": "Data e ora", - "actor": "Attore", - "action": "Azione", - "resource": "Risorsa", - "status": "Stato", - "ip": "IP", - "loading": "Caricamento…", - "emptyTitle": "Nessuna voce corrisponde a questi filtri.", - "emptyHint": "Prova a cancellare i filtri o ad ampliare l'intervallo di date.", - "system": "sistema", - "view": "Visualizza" - }, - "drawer": { - "entry": "voce #{{id}}", - "overview": "Panoramica", - "raw": "JSON grezzo", - "error": "Errore", - "actor": "Attore", - "resource": "Risorsa", - "ip": "IP", - "userAgent": "User agent", - "session": "Sessione", - "metadata": "Metadati", - "copy": "Copia", - "copied": "Copiato", - "copyJson": "Copia JSON" - } - }, - "team": { - "title": "Team", - "subtitle": "Gestisci gli utenti e i loro ruoli.", - "tabs": { - "members": "Membri", - "roles": "Ruoli e permessi" - }, - "toast": { - "rolesLoadFailed": "Impossibile caricare i ruoli", - "userLoadFailed": "Impossibile caricare l'utente", - "rolesUpdated": "Ruoli aggiornati", - "userReactivated": "Utente riattivato", - "userDeactivated": "Utente disattivato", - "tfaReset": "Autenticazione a due fattori reimpostata", - "invitationSent": "Invito inviato", - "loginOrEmailInUse": "Questo nome utente o email è già in uso", - "invalidRequest": "Richiesta non valida", - "noPermission": "Non hai il permesso di farlo", - "userNotFound": "Utente non trovato", - "operationFailed": "Operazione non riuscita", - "emailInUse": "Questa e-mail è già in uso", - "roleCreated": "Ruolo creato", - "roleUpdated": "Ruolo aggiornato", - "roleDeleted": "Ruolo eliminato", - "roleNameInUse": "Esiste già un ruolo con questo identificatore", - "roleImmutable": "I ruoli di sistema non possono essere modificati", - "permissionsLoadFailed": "Impossibile caricare i permessi", - "localUserCreated": "Utente locale creato" - }, - "members": { - "searchPlaceholder": "Cerca per nome o e-mail…", - "invite": "Invita utente", - "colUser": "Utente", - "colRoles": "Ruoli", - "col2fa": "2FA", - "colStatus": "Stato", - "loading": "Caricamento utenti…", - "loadFailed": "Impossibile caricare gli utenti.", - "retry": "Riprova", - "noSearchMatch": "Nessun utente corrisponde alla ricerca.", - "none": "Nessun utente ancora.", - "noRole": "nessuno", - "on": "Sì", - "off": "No", - "countLabel_one": "{{count}} utente · pagina {{page}} di {{pages}}", - "countLabel_other": "{{count}} utenti · pagina {{page}} di {{pages}}", - "federated": "SSO" - }, - "status": { - "inactive": "Inattivo", - "pendingPassword": "Password in sospeso", - "active": "Attivo", - "pending": "Invito in sospeso", - "suspended": "Sospeso" - }, - "drawer": { - "createdBy": "creato da {{actor}}", - "loading": "Caricamento…", - "profileTitle": "Profilo", - "profileSubtitle": "Solo l'utente può modificare questi dati, dal proprio profilo.", - "name": "Nome", - "username": "Nome utente", - "email": "Email", - "language": "Lingua", - "accountTitle": "Account", - "status": "Stato", - "statusActive": "Attivo", - "statusInactive": "Inattivo", - "tfa": "2FA", - "tfaEnabled": "Attiva", - "tfaNotConfigured": "Non configurato", - "resetTfa": "Reimposta", - "resetTfaHint": "Disattiva il 2FA di questo utente così potrà riconfigurarlo al prossimo accesso", - "resetTfaConfirmTitle": "Reimpostare l'autenticazione a due fattori?", - "resetTfaConfirmBody": "Questo disattiva il 2FA di {{name}}. Accederà solo con la password e potrà riconfigurarlo dal proprio profilo.", - "resetTfaConfirm": "Reimposta 2FA", - "pendingPasswordNote": "Usa ancora la password temporanea (invito non completato).", - "lastModified": "Modificato {{time}}", - "rolesTitle": "Ruoli", - "rolesSubtitle": "I ruoli concedono permessi di modulo. Un utente può averne più di uno.", - "noRoleWarning": "Nessun ruolo assegnato — l'utente non avrà accesso ai moduli.", - "deactivate": "Disattiva", - "reactivate": "Riattiva", - "waitingInvite": "In attesa che l'utente accetti l'invito.", - "cancel": "Annulla", - "saving": "Salvataggio…", - "saveRoles": "Salva ruoli", - "created": "creato {{time}}", - "pendingNote": "L'invito non è ancora stato accettato.", - "federatedNote": "Accede tramite un provider di identità." - }, - "invite": { - "title": "Invita utente", - "description": "L'account viene creato inattivo. L'utente riceve un'e-mail per impostare la password e attivarlo.", - "username": "Nome utente", - "usernameHint": "Almeno 3 caratteri.", - "email": "Email", - "firstName": "Nome", - "lastName": "Cognome", - "roles": "Ruoli", - "cancel": "Annulla", - "sending": "Invio…", - "send": "Invia invito", - "name": "Nome", - "emailHint": "È l'indirizzo con cui accederà.", - "localDescription": "L'account viene creato con una password e attivato immediatamente. Non viene inviata alcuna e-mail.", - "modeInvite": "Invita utente", - "modeLocal": "Crea utente locale", - "passwordLabel": "Password", - "passwordPlaceholder": "Imposta una password forte", - "localUserNote": "Questo utente non riceverà un'e-mail e verrà attivato automaticamente.", - "createLocal": "Crea utente", - "passwordRules": { - "length": "Almeno 8 caratteri", - "case": "Almeno un carattere maiuscolo e uno minuscolo", - "special": "Almeno un carattere speciale" - }, - "emailInvalid": "Inserisci un indirizzo e-mail valido" - }, - "rolePicker": { - "none": "Nessun ruolo disponibile." - }, - "roles": { - "loading": "Caricamento ruoli…", - "loadFailed": "Impossibile caricare i permessi dei ruoli.", - "readonlyNote": "I ruoli e i loro permessi sono definiti dal sistema e di sola lettura. Assegnali agli utenti dalla scheda Membri.", - "permissionsCount_one": "{{count}} permesso", - "permissionsCount_other": "{{count}} permessi", - "modulesCount_one": "{{count}} modulo", - "modulesCount_other": "{{count}} moduli", - "matrixTitle": "Matrice dei permessi", - "matrixSubtitle": "Cosa può fare ogni ruolo, per modulo.", - "permission": "Permesso", - "systemNote": "I ruoli di sistema fanno parte della piattaforma e non sono modificabili. Quelli che crei appartengono a questo tenant.", - "newRole": "Nuovo ruolo", - "edit": "Modifica", - "delete": "Elimina", - "systemBadge": "Sistema", - "createTitle": "Nuovo ruolo", - "editTitle": "Modifica ruolo", - "editorSubtitle": "Scegli cosa può fare questo ruolo. Un utente può averne più di uno.", - "nameLabel": "Identificatore", - "nameHint": "Usato nel codice e nell'API. Ad esempio ROLE_AUDITOR.", - "displayNameLabel": "Nome visualizzato", - "descriptionLabel": "Descrizione", - "permissionsLabel": "Permessi", - "selectedCount": "{{count}} selezionati", - "toggleAll": "tutti", - "loadingPermissions": "Caricamento permessi…", - "save": "Salva ruolo", - "deleteConfirmTitle": "Eliminare questo ruolo?", - "deleteConfirmBody": "{{name}} verrà rimosso. Chi ha solo questo ruolo resterà senza accesso ai moduli." - }, - "langDefault": "Predefinito di sistema", - "relative": { - "justNow": "proprio ora", - "minutesAgo": "{{count}} min fa", - "hoursAgo": "{{count}} h fa", - "daysAgo": "{{count}} g fa" - }, - "roleNames": { - "ROLE_ADMIN": "Amministratore", - "ROLE_USER": "Utente" - }, - "roleDescriptions": { - "ROLE_ADMIN": "Accesso completo a tutte le risorse", - "ROLE_USER": "Utente standard con accesso in lettura a livello di modulo" - }, - "actions": { - "read": "Lettura", - "write": "Scrittura", - "delete": "Eliminazione" - }, - "resources": { - "adaudit": "Audit AD", - "alerts": "Avvisi", - "audit": "Registro di audit", - "compliance": "Conformità", - "config": "Configurazione", - "dashboards": "Dashboard", - "datasources": "Datasources", - "eventprocessing": "Elaborazione eventi", - "idp": "Provider di identità", - "incidents": "Incidenti", - "integrations": "Integrazioni", - "loganalyzer": "Analizzatore di log", - "opensearch": "OpenSearch", - "roles": "Ruoli", - "soar": "SOAR", - "users": "Utenti", - "notifications": "Notifiche", - "socai": "SOC AI", - "tenant": "Tenant", - "threatintel": "Threat intelligence" - } - }, - "apiKeys": { - "title": "Chiavi API", - "subtitle": "Token di accesso programmatico per l’API di UTMStack.", - "new": "Nuova chiave API", - "searchPlaceholder": "Cerca per nome o IP consentito…", - "refresh": "Aggiorna", - "loading": "Caricamento chiavi API…", - "loadFailed": "Impossibile caricare le chiavi API.", - "retry": "Riprova", - "noSearchMatch": "Nessuna chiave API corrisponde alla ricerca.", - "empty": "Ancora nessuna chiave API. Creane una per iniziare.", - "anyIp": "Qualsiasi IP", - "never": "Mai", - "count_one": "{{count}} chiave · pagina {{page}} di {{pages}}", - "count_other": "{{count}} chiavi · pagina {{page}} di {{pages}}", - "enterprise": { - "title": "Le chiavi API sono una funzione Enterprise", - "body": "Emetti, limita e ruota le chiavi API per l’accesso programmatico all’API di UTMStack. Questa funzionalità è disponibile nell’edizione Enterprise.", - "upgrade": "Passa a Enterprise", - "manageLicense": "Gestisci la tua licenza" - }, - "col": { - "name": "Nome", - "allowedIps": "IP consentiti", - "created": "Creata", - "lastRotated": "Ultima rotazione", - "expires": "Scade", - "status": "Stato", - "actions": "Azioni" - }, - "status": { - "active": "Attiva", - "expiring": "In scadenza", - "expired": "Scaduta" - }, - "action": { - "rotate": "Ruota", - "edit": "Modifica", - "delete": "Elimina" - }, - "dialog": { - "editTitle": "Modifica chiave API", - "newTitle": "Nuova chiave API", - "name": "Nome", - "namePlaceholder": "ci-pipeline", - "allowedIps": "IP consentiti", - "allowedIpsHint": "Separati da virgola. Lascia vuoto per consentire qualsiasi IP.", - "expires": "Scade", - "expiresHint": "Lascia vuoto per una chiave che non scade mai.", - "secretNote": "Il token segreto viene mostrato una sola volta, subito dopo la creazione. Copialo allora — non può essere recuperato in seguito (solo ruotato).", - "cancel": "Annulla", - "saving": "Salvataggio…", - "saveChanges": "Salva modifiche", - "createKey": "Crea chiave" - }, - "confirm": { - "deleteTitle": "Elimina chiave API", - "rotateTitle": "Ruota chiave API", - "deleteBody": "Eliminare {{name}}? Qualsiasi client che la utilizza perderà immediatamente l’accesso. Questa azione non può essere annullata.", - "rotateBody": "Ruotare {{name}}? Viene emesso un nuovo segreto e quello attuale smette di funzionare immediatamente. Il nuovo token viene mostrato una sola volta.", - "cancel": "Annulla", - "working": "In corso…", - "delete": "Elimina", - "rotate": "Ruota" - }, - "reveal": { - "title": "Chiave API creata", - "note": "Copia questo segreto ora — per {{name}}. Non verrà più mostrato. Se lo perdi, ruota la chiave.", - "copied": "Copiato", - "copy": "Copia", - "done": "Fatto" - }, - "toast": { - "updated": "Chiave API aggiornata", - "secretIssueFailed": "Chiave creata, ma non è stato possibile emettere il segreto. Usa Ruota per ottenerne uno.", - "deleted": "Chiave API eliminata" - }, - "error": { - "nameTaken": "Esiste già una chiave API con quel nome", - "enterpriseRequired": "Le chiavi API richiedono l’edizione Enterprise", - "notFound": "Chiave API non trovata", - "invalidRequest": "Richiesta non valida", - "failed": "Operazione non riuscita" - } - }, - "idp": { - "title": "Provider di identità", - "subtitle": "Single sign-on SAML 2.0 per la tua organizzazione.", - "add": "Aggiungi provider", - "enterprise": { - "title": "L'SSO è una funzione Enterprise", - "body": "Collega un provider di identità SAML 2.0 (Entra ID, Okta, Google Workspace…) per far accedere il tuo team con il tuo IdP. Il single sign-on è disponibile nell'edizione Enterprise.", - "upgrade": "Passa a Enterprise" - }, - "loading": "Caricamento provider di identità…", - "loadFailed": "Impossibile caricare i provider di identità.", - "retry": "Riprova", - "empty": { - "title": "Nessun provider di identità configurato", - "body": "Aggiungi un provider SAML 2.0 per far accedere il tuo team con il tuo IdP aziendale." - }, - "card": { - "enable": "Abilita", - "disable": "Disabilita", - "active": "Attivo", - "disabled": "Disabilitato", - "metadataUrl": "URL metadati", - "spEntityId": "SP Entity ID", - "spAcsUrl": "SP ACS URL", - "loginUrl": "URL di accesso", - "copy": "Copia", - "edit": "Modifica", - "delete": "Elimina", - "jit": "Provisioning", - "jitOn": "creates accounts on first sign-in", - "sync": "Roles", - "syncOn": "re-applied on every sign-in" - }, - "form": { - "addTitle": "Aggiungi provider di identità", - "editTitle": "Modifica provider di identità", - "name": "Nome", - "nameHint": "Univoco. Usato nell'URL SSO.", - "providerType": "Tipo di provider", - "providerTypeHint": "Un'etichetta, es. azure, okta, google.", - "metadataUrl": "URL metadati dell'IdP", - "spEntityId": "SP Entity ID", - "spAcsUrl": "SP ACS URL", - "certificate": "Certificato SP (PEM)", - "privateKey": "Chiave privata SP (PEM)", - "privateKeyHintEdit": "Lascia vuoto per mantenere la chiave salvata.", - "privateKeyHintCreate": "Obbligatoria. Salvata cifrata; non verrà più mostrata.", - "privateKeyUnchanged": "•••••••• (invariata)", - "active": "Attivo (mostra nella pagina di accesso)", - "cancel": "Annulla", - "saving": "Salvataggio…", - "save": "Salva modifiche", - "create": "Crea provider", - "issuer": "Issuer URL", - "issuerHint": "Discovery runs against this; the provider must serve /.well-known/openid-configuration under it.", - "clientId": "Client ID", - "redirectUrl": "Redirect URL", - "redirectUrlHint": "Register this exact URL with the provider.", - "host": "Host", - "port": "Port", - "startTls": "TLS", - "startTlsOn": "Use StartTLS", - "bindDn": "Bind DN", - "bindDnHint": "A service account that may search the directory.", - "baseDn": "Base DN", - "userFilter": "User filter", - "userFilterHint": "Must contain %s, where the address typed at login is placed.", - "emailAttribute": "Email attribute", - "nameAttribute": "Name attribute", - "groupAttribute": "Group attribute", - "provisioning": "Accounts and roles", - "provisioningHint": "What happens when someone the directory vouches for signs in.", - "jit": "Create the account on first sign-in", - "defaultRole": "Default role", - "defaultRoleHint": "Given when no group matches. Without one, an unmatched sign-in is refused.", - "noDefaultRole": "None", - "groupsAttribute": "Groups attribute", - "groupsAttributeHint": "Where the provider puts group membership.", - "syncRoles": "Re-apply roles on every sign-in", - "syncRolesHint": "Roles not in the mapping are removed, so a change in the directory reaches here. Without this, a demotion never arrives.", - "mappings": "Group to role", - "mappingsHint": "A directory group on the left, the role it grants on the right.", - "addMapping": "Add", - "noMappings": "No mappings. Everyone gets the default role.", - "groupPlaceholder": "SOC Analysts", - "pickRole": "Pick a role", - "secret.saml": "SP private key", - "secret.oidc": "Client secret", - "secret.ldap": "Bind password", - "secretHintCreate": "Stored encrypted and never shown again.", - "secretHintEdit": "Leave blank to keep the stored one.", - "secretUnchanged": "invariato", - "errors": { - "required": "Questo campo è obbligatorio.", - "url": "Deve essere un URL http(s) valido.", - "httpsUrl": "Deve essere un URL https valido.", - "hostname": "Immettere un host o un IP senza schema (es. ldap.esempio.it).", - "port": "La porta deve essere un numero intero tra 0 e 65535.", - "pemCertificate": "Non sembra un certificato PEM (manca -----BEGIN/END CERTIFICATE-----).", - "pemKey": "Non sembra una chiave privata PEM (manca -----BEGIN/END PRIVATE KEY-----).", - "userFilterPlaceholder": "Il filtro deve contenere %s, dove viene inserita l'indirizzo di accesso.", - "userFilterUnbalanced": "Parentesi non bilanciate: la ricerca non restituirà nulla.", - "nameFormat": "Usa lettere, numeri, punti, trattini o underscore (max 64). Compare nell'URL SSO, quindi niente spazi.", - "redirectUrl": "Deve essere un URL https valido oppure un URL http di loopback (localhost / 127.0.0.1 / [::1]).", - "entityId": "Deve essere un URI valido, es. https://utmstack.example.com/sp." - } - }, - "delete": { - "title": "Elimina provider di identità", - "body": "Eliminare {{name}}? Gli utenti non potranno più accedere tramite esso. L'operazione non può essere annullata.", - "cancel": "Annulla", - "deleting": "Eliminazione…", - "confirm": "Elimina" - }, - "toast": { - "enabled": "Provider abilitato", - "disabled": "Provider disabilitato", - "created": "Provider di identità creato", - "updated": "Provider di identità aggiornato", - "deleted": "Provider di identità eliminato", - "paidPlan": "L'SSO SAML richiede un piano a pagamento", - "enterpriseRequired": "L'SSO richiede l'edizione Enterprise", - "notFound": "Provider di identità non trovato", - "invalid": "Configurazione non valida", - "failed": "Operazione non riuscita" - }, - "providerType": { - "saml": "SAML 2.0", - "oidc": "OpenID Connect", - "ldap": "LDAP / Active Directory", - "comingSoon": "non ancora disponibile" - } - }, - "userAuditor": { - "title": "Auditor utenti", - "subtitle": "Account di Active Directory osservati nei tuoi log di sicurezza di Windows — rilevati da eventi di creazione, accesso ed eliminazione.", - "export": "Esporta", - "accountsChip": "{{count}} account", - "overview": { - "title": "Inventario account", - "active": "attivi", - "disabled": "disabilitati", - "deleted": "eliminati", - "seen24h": "{{count}} visti nelle ultime 24 ore", - "byDomain": "Per dominio" - }, - "views": { - "all": "Tutti gli account", - "windows": "Windows", - "linux": "Linux", - "active": "Attivi", - "disabled": "Disabilitati", - "deleted": "Eliminati", - "service": "Account di servizio", - "stale": "Inattivi (30g+)" - }, - "searchPlaceholder": "Cerca per nome account o SID…", - "allTenants": "Tutti i tenant", - "filters": { - "add": "Aggiungi filtro", - "clearAll": "Cancella tutto", - "filterValues": "Filtra valori…", - "loadingValues": "Caricamento valori…", - "noValues": "Nessun valore trovato.", - "pickValue": "Scegli un valore per aggiungere il filtro.", - "empty": "(vuoto)", - "cancel": "Annulla", - "addBtn": "Aggiungi" - }, - "filterFields": { - "status": "Stato del ciclo di vita" - }, - "ops": { - "is": "è" - }, - "refresh": "Aggiorna", - "layout": { - "list": "Elenco", - "cards": "Schede" - }, - "list": { - "account": "Account", - "identity": "Identità", - "sid": "SID", - "status": "Stato", - "lastLogon": "Ultimo accesso", - "lastSeen": "Visto l’ultima volta", - "tenant": "Tenant" - }, - "status": { - "active": "Attivo", - "disabled": "Disabilitato", - "deleted": "Eliminato" - }, - "badge": { - "service": "servizio", - "stale": "inattivo" - }, - "empty": "Nessun account corrisponde a questa vista.", - "loadError": "Impossibile caricare gli account AD.", - "retry": "Riprova", - "card": { - "lastLogon": "Ultimo accesso" - }, - "pageInfo": "{{from}}–{{to}} di {{count}}", - "drawer": { - "tenantInline": "tenant {{id}}", - "serviceAccount": "account di servizio", - "stale": "inattivo 30g+", - "viewInLogs": "Vedi eventi nel Log Explorer", - "copySid": "Copia SID", - "copyUid": "Copia identità", - "copied": "Copiato", - "identity": "Identità", - "accountName": "Nome account", - "domain": "Dominio", - "hostname": "Hostname", - "sid": "SID", - "uidNumber": "UID", - "machineId": "ID macchina", - "tenant": "Tenant", - "adStatus": "Stato AD", - "enabled": "Abilitato", - "disabled": "Disabilitato", - "lifecycle": "Ciclo di vita", - "created": "Account creato", - "lastLogon": "Ultimo accesso", - "lastSeen": "Visto l’ultima volta nei log", - "deleted": "Account eliminato", - "noLifecycle": "Nessun evento del ciclo di vita registrato." - }, - "relative": { - "justNow": "proprio ora", - "minutesAgo": "{{count}}m fa", - "hoursAgo": "{{count}}h fa", - "daysAgo": "{{count}}g fa" - }, - "none": "—" - }, - "connectionKey": { - "title": "Chiave di connessione", - "subtitle1": "La chiave che gli agenti presentano quando si registrano su questa istanza.", - "subtitleEmphasis": "Viene usata solo per l'installazione degli agenti", - "subtitle2": "— non per i collector, le integrazioni o l'API. È gestita dall'agent-manager.", - "status": { - "label": "Stato", - "loading": "Caricamento…", - "unavailable": "Agent-manager non disponibile", - "active": "Attiva", - "unavailableHint": "Impossibile contattare l'agent-manager per leggere la chiave.", - "activeHint": "Gli agenti possono registrarsi con questa chiave." - }, - "token": { - "title": "Chiave di connessione", - "subtitle": "Tratta questo valore come una credenziale. Ruotarla emette una nuova chiave per le future installazioni degli agenti — gli agenti già registrati continuano a funzionare.", - "loadFailedTitle": "Impossibile caricare la chiave di connessione", - "unavailableTitle": "Chiave di connessione non disponibile", - "loadFailedHint": "La chiave è gestita dall'agent-manager, che non ha risposto. Riprova tra un momento.", - "retry": "Riprova", - "show": "Mostra chiave", - "hide": "Nascondi chiave", - "copy": "Copia", - "copied": "Copiato", - "regenerate": "Rigenera chiave di connessione", - "confirmTitle": "Rigenerare la chiave?", - "confirmBody": "Le nuove installazioni degli agenti avranno bisogno della nuova chiave. Gli agenti già registrati continuano a funzionare. Operazione irreversibile.", - "regenerating": "Rigenerazione…", - "confirmYes": "Sì, rigenera", - "cancel": "Annulla" - }, - "security": { - "title": "Raccomandazioni di sicurezza", - "subtitle": "Buone pratiche per proteggere questa credenziale.", - "rotateTitle": "Ruota ogni 90 giorni", - "rotateBody": "Pianifica una rotazione ricorrente. UTMStack può inviarti un promemoria via email quando la chiave ha più di 90 giorni.", - "rotateAction": "Configura promemoria", - "secretTitle": "Conservala come segreto", - "secretBody": "Non inserirla nel controllo di versione. Usa il tuo gestore di segreti (Vault, AWS SM, ecc.) e iniettala al momento dell'installazione.", - "auditTitle": "Verifica chi l'ha recuperata", - "auditBody": "Ogni recupero e rotazione è registrato nel log di audit dell'applicazione.", - "auditAction": "Vedi log di audit" - }, - "toast": { - "loadFailed": "Impossibile caricare la chiave di connessione", - "rotated": "Chiave di connessione ruotata", - "rotateFailed": "Impossibile ruotare la chiave di connessione", - "copyFailed": "Impossibile copiare" - } - }, - "dataRetention": { - "title": "Conservazione dei dati", - "subtitle": "How long each dataset is kept, and when its records stop costing local disk.", - "loading": "Caricamento…", - "loadFailed": "Could not read the store.", - "retry": "Riprova", - "datasets": { - "logs": "Logs", - "alerts": "Alerts", - "statistics": "Ingestion statistics" - }, - "holding": "{{documents}} records · {{size}}", - "since": "since {{date}}", - "diskUsed": "Disk {{pct}}% used", - "keep": "Delete after", - "keepHint": "A record is deleted this many days after it happened, wherever it is stored by then.", - "cold": "Move to cold storage after", - "coldHint": "Older records move to object storage and stay queryable. 0 keeps everything on local disk.", - "coldUnavailable": "Set up cold storage below to move older records off local disk.", - "coldBeforeDelete": "Records have to move before they are deleted: use fewer days than the lifetime, or 0.", - "tieredNote": "This dataset moves records to cold storage. Going back to local-only needs the table rebuilt, so it cannot be turned off here.", - "days": "giorni", - "save": "Salva", - "saving": "Salvataggio…", - "toast": { - "saved": "Retention saved", - "noPermission": "You do not have permission to change retention", - "saveFailed": "Could not save the retention" - }, - "coldStorage": { - "title": "Cold storage", - "hint": "An object store the event store treats as a second, slower disk. Older records move there and are still queried from the same place — it is not an archive and nothing has to be restored.", - "active": "In use", - "inactive": "Not set up", - "writtenNotReady": "The bucket is configured but the store has not picked it up. Check that the deployment shares the store's configuration directory.", - "endpoint": "Bucket URL", - "accessKey": "Access key", - "secretKey": "Secret key", - "bucketLocked": "The credentials can be changed at any time. The bucket cannot, once records live in it: the parts already moved carry it.", - "enable": "Enable cold storage", - "update": "Update credentials", - "toast": { - "saved": "Cold storage configured", - "failed": "Could not configure cold storage" - }, - "kind": "Tipo", - "kind_s3": "Archivio oggetti compatibile S3", - "kind_local": "Cartella locale o NFS", - "kind_azure": "Azure Blob Storage", - "accountUrl": "URL dell'account di archiviazione", - "container": "Contenitore", - "accountName": "Nome account", - "accountKey": "Chiave account", - "useRole": "Usa il ruolo IAM del server invece delle chiavi", - "s3Hint": "Funziona con AWS S3 e qualsiasi archivio compatibile S3: MinIO, Ceph, Wasabi, Cloudflare R2 o Google Cloud Storage (endpoint https://storage.googleapis.com// con chiavi HMAC).", - "localHint": "I record passano alla cartella montata su /mnt/utmstack-cold nell'archivio eventi: una directory normale nella cartella dati, oppure una condivisione NFS montata sull'host su /clickhouse/cold prima dell'avvio dello stack. Nessuna credenziale richiesta.", - "changeWarning": "Records already moved to the current destination are not migrated. They stay there and stop being readable from here until the old destination is copied across by hand." - }, - "forbidden": { - "title": "Questa pagina è della piattaforma", - "body": "La conservazione riguarda le tabelle condivise da tutti i tenant: solo un amministratore della piattaforma può leggerla o modificarla." - } - }, - "languageSettings": { - "title": "Lingua della piattaforma", - "subtitle": "Lingua predefinita per le schermate pre-login, le email di sistema e i nuovi utenti. Ogni utente può comunque scegliere la propria nel profilo.", - "label": "Lingua predefinita", - "hint": "Usata quando un utente non ha scelto la propria lingua.", - "save": "Salva", - "saving": "Salvataggio…", - "saved": "Lingua della piattaforma aggiornata", - "loadError": "Impossibile caricare l'impostazione della lingua", - "saveError": "Impossibile salvare l'impostazione della lingua" - }, - "branding": { - "title": "Brand", - "subtitle": "Personalizza UTMStack con l’identità della tua organizzazione — applicata ovunque: schermata di accesso, barra laterale, email e report.", - "enterpriseRequired": "Il white-label è una funzione Enterprise.", - "manageLicense": "Gestisci licenza", - "enable": { - "title": "White-label", - "description": "Sostituisci il marchio UTMStack con il tuo su tutta la piattaforma.", - "label": "Attiva il white-label" - }, - "identity": { - "title": "Identità", - "productName": "Nome del prodotto", - "productNameHint": "Mostrato nella barra del titolo, nella barra laterale e nelle email.", - "accent": "Colore d’accento", - "accentHint": "Colore primario per pulsanti, link e stati attivi.", - "custom": "Colore personalizzato" - }, - "logos": { - "title": "Loghi", - "hint": "PNG, SVG, WEBP, JPG o ICO. Fino a 5 MB.", - "logo": "Logo (chiaro)", - "logoDark": "Logo (scuro)", - "favicon": "Favicon" - }, - "reports": { - "title": "Risorse report", - "hint": "Incorporate nei report PDF generati.", - "reportLogo": "Logo report", - "reportCover": "Copertina report" - }, - "asset": { - "upload": "Carica", - "replace": "Sostituisci" - }, - "save": "Salva modifiche", - "saving": "Salvataggio…", - "saved": "Brand aggiornato", - "saveError": "Impossibile salvare il brand", - "uploaded": "Immagine caricata", - "uploadError": "Impossibile caricare l’immagine", - "loadError": "Impossibile caricare il brand", - "enterprise": { - "title": "Il white label è una funzione Enterprise", - "body": "Sostituisci il nome del prodotto, il logo e la copertina dei report con i tuoi, così il pannello e tutto ciò che genera portano il tuo marchio invece di quello di UTMStack.", - "upgrade": "Passa a Enterprise" - }, - "restore": "Ripristina i valori UTMStack", - "restored": "Marchio ripristinato ai valori UTMStack" - }, - "emailConfig": { - "title": "Configurazione email", - "subtitle": "Server SMTP usato per inviare notifiche di avvisi, report ed email dell’account.", - "server": { - "title": "Server SMTP", - "host": "Host", - "hostHint": "Nome host del tuo server SMTP.", - "port": "Porta", - "encryption": "Crittografia", - "username": "Nome utente", - "password": "Password", - "passwordSetHint": "È salvata una password. Lascia vuoto per mantenerla o digitane una nuova per cambiarla." - }, - "encryptionOpt": { - "TLS": "TLS", - "SSL": "SSL", - "NONE": "Nessuna" - }, - "sender": { - "title": "Mittente", - "from": "Indirizzo mittente", - "fromHint": "Indirizzo da cui vengono inviate le email.", - "organization": "Nome organizzazione", - "organizationHint": "Mostrato nelle email di notifica di avvisi e incidenti.", - "baseUrl": "URL base", - "baseUrlHint": "URL pubblico di questa istanza, usato per i link nelle email." - }, - "test": { - "button": "Invia test", - "sending": "Invio…", - "sentTo": "Verrà inviata un’email di prova a {{email}}.", - "success": "Email di prova inviata a {{email}}", - "fail": "Impossibile inviare l’email di prova", - "fromRequired": "Imposta un indirizzo mittente prima di testare" - }, - "save": "Salva modifiche", - "saving": "Salvataggio…", - "saved": "Configurazione email salvata", - "saveError": "Impossibile salvare la configurazione", - "loadError": "Impossibile caricare la configurazione", - "recipients": { - "alertsTitle": "Destinatari degli avvisi", - "incidentsTitle": "Destinatari degli incidenti", - "to": "A", - "cc": "CC", - "alertsHelper": "Indirizzi avvisati quando vengono generati nuovi avvisi. Se lasci il campo vuoto, gli avvisi non vengono inviati per email.", - "incidentsHelper": "Indirizzi avvisati alla creazione di un incidente. Se lasci il campo vuoto, gli incidenti non vengono inviati per email.", - "add": "Aggiungi" - } - }, - "dateFormat": { - "title": "Data e ora", - "subtitle": "Come vengono visualizzati i timestamp nella piattaforma. I log sono sempre archiviati in UTC.", - "timezone": { - "title": "Fuso orario", - "hint": "I timestamp vengono mostrati in questo fuso orario. I dati restano archiviati in UTC.", - "system": "Predefinito del browser", - "now": "Ora: {{value}}" - }, - "format": { - "title": "Formato data", - "hint": "Stile usato per date e orari." - }, - "styles": { - "short": "Breve", - "medium": "Medio", - "long": "Lungo", - "full": "Completo" - }, - "save": "Salva modifiche", - "saving": "Salvataggio…", - "saved": "Impostazioni data salvate", - "saveError": "Impossibile salvare le impostazioni", - "loadError": "Impossibile caricare le impostazioni" - }, - "about": { - "title": "Informazioni su questa istanza", - "subtitle": "Versione, licenza e stato del sistema di questo deployment UTMStack.", - "loading": "Caricamento delle informazioni dell'istanza…", - "edition": { - "enterprise": "Enterprise", - "community": "Community" - }, - "fields": { - "hostname": "Server", - "instanceId": "ID istanza", - "noInstanceMeta": "Nessun metadato dell'istanza disponibile." - }, - "license": { - "title": "Licenza", - "enterpriseMssp": "Enterprise · MSSP", - "datasources": "Datasources", - "communityLimited": "Limite Community", - "unlimited": "Illimitato", - "expires": "Scade", - "managedNote": "Edizione, limiti dei datasources e caricamento licenza si gestiscono nella pagina Licenza.", - "view": "Vedi licenza", - "ingest": "Volume di ingest", - "notMetered": "Non misurato", - "gbPerMonth": "{{gb}} GB/mese" - }, - "services": { - "backend": { - "name": "Backend API", - "desc": "Gateway REST, autenticazione e orchestrazione dei moduli." - }, - "opensearch": { - "name": "OpenSearch", - "desc": "Archiviazione di log ed eventi.", - "detail": "{{nodes}} nodi · {{shards}} shard" - }, - "unreachable": "Irraggiungibile" - }, - "status": { - "up": "Integro", - "degraded": "Degradato", - "down": "Non attivo", - "unknown": "Sconosciuto" - }, - "health": { - "title": "Stato del sistema", - "allHealthy": "Tutti i servizi integri. Aggiorna per ricontrollare.", - "issues_one": "{{count}} servizio richiede attenzione.", - "issues_other": "{{count}} servizi richiedono attenzione.", - "refresh": "Aggiorna" - }, - "usage": { - "title": "Origini dati", - "subtitle": "Origini dati configurate in questa installazione.", - "ofUnlimited": "di illimitato", - "ofLimit": "di {{limit}}", - "overLimit": "Oltre il limite della licenza — i dati oltre il limite sono a rischio.", - "configured": "configurate" - }, - "support": { - "title": "Supporto", - "docs": "Documentazione", - "repo": "Repository GitHub", - "issues": "Segnala un problema", - "website": "utmstack.com" - }, - "legal": { - "title": "Note legali", - "license": "Licenza", - "security": "Divulgazione di sicurezza", - "copyright": "© {{year}} UTMStack. Tutti i diritti riservati." - } - }, - "logExplorer": { - "title": "Esploratore di log", - "eventsIn": "eventi in", - "searching": "Ricerca…", - "query": { - "allDataTypes": "Tutti i tipi di dato", - "dataTypes": "Tipi di dato", - "exportCsv": "Esporta CSV", - "filterDataTypes": "Filtra tipi di dato…", - "noDataTypes": "Nessun tipo di dato", - "noDataTypesMatch": "Nessun tipo di dato corrispondente", - "noTextSearch": "Questa origine non ha un campo full-text — filtra per campo", - "refresh": "Aggiorna", - "run": "Esegui", - "search": "Cerca", - "searchPlaceholder": "Cerca in tutti i campi…" - }, - "time": { - "15m": "Ultimi 15 minuti", - "1h": "Ultima ora", - "6h": "Ultime 6 ore", - "24h": "Ultime 24 ore", - "7d": "Ultimi 7 giorni", - "30d": "Ultimi 30 giorni" - }, - "ops": { - "is": "è", - "isNot": "non è", - "contains": "contiene", - "exists": "esiste", - "between": "tra", - "search": "cerca", - "isOneOf": "è uno di", - "isNotOneOf": "non è nessuno di", - "doesNotContain": "no contiene", - "startsWith": "empieza con", - "doesNotStartWith": "no empieza con", - "endsWith": "termina con", - "doesNotEndWith": "no termina con", - "doesNotExist": "no existe", - "notBetween": "no está entre", - "greaterThan": "es mayor que", - "greaterThanOrEquals": "es mayor o igual que", - "lessThan": "es menor que", - "lessThanOrEquals": "es menor o igual que" - }, - "filters": { - "label": "Filtri", - "clearAll": "Cancella tutto" - }, - "fields": { - "title": "Campi", - "filterPlaceholder": "Filtra campi…", - "none": "Nessun campo", - "selected": "Campi selezionati", - "available": "Campi disponibili", - "topValues_one": "Top {{count}} valore", - "topValues_other": "Top {{count}} valori", - "loading": "Caricamento…", - "noValues": "Nessun valore", - "addColumn": "Aggiungi come colonna", - "removeColumn": "Rimuovi colonna dalla tabella", - "filterFor": "Filtra per il valore", - "filterOut": "Escludi il valore", - "empty": "(vuoto)" - }, - "results": { - "dataTypesFailed": "Impossibile caricare i tipi di dato.", - "endOfResults": "{{count}} eventi caricati", - "loadingMore": "Caricamento in corso…", - "message": "Messaggio", - "none": "Nessun log corrisponde a questa query.", - "removeColumn": "Rimuovi {{field}}", - "retry": "Riprova", - "searchFailed": "Ricerca fallita.", - "searching": "Ricerca…", - "source": "Origine", - "time": "Ora", - "scope": "Cercato in {{dataset}} · {{dataType}}.", - "searchAllDataTypes": "Cerca in tutti i tipi" - }, - "detail": { - "fieldsCount_one": "{{count}} campo", - "fieldsCount_other": "{{count}} campi", - "copyJson": "Copia JSON", - "copied": "Documento copiato", - "parsedFields": "Campi analizzati", - "json": "JSON", - "filterFor": "Filtra per", - "filterOut": "Escludi", - "surrounding": "Eventi circostanti", - "surroundingHint": "Mostra gli eventi ±15 min attorno a questo, dalla stessa sorgente" - }, - "view": { - "table": "Tabella", - "chart": "Grafico" - }, - "chart": { - "aggregateOn": "Aggrega su", - "per": "per", - "topValues": "— top 20 valori", - "building": "Creazione grafico…", - "failed": "Impossibile creare il grafico per questo campo.", - "noData": "Nessun dato da graficare." - }, - "intervals": { - "minute": "Minuto", - "hour": "Ora", - "day": "Giorno", - "week": "Settimana", - "month": "Mese", - "quarter": "Trimestre", - "year": "Anno" - }, - "toast": { - "exportFailed": "Esportazione fallita" - }, - "builder": { - "add": "Aggiungi filtro", - "filterValues": "Filtra valori…", - "loadingValues": "Caricamento valori…", - "noValues": "Nessun valore.", - "cancel": "Annulla", - "confirm": "Aggiungi", - "pickValue": "Pick a value to add the filter." - }, - "related": { - "nLogs_one": "{{count}} log", - "nLogs_other": "{{count}} log", - "truncated": "Mostrando i primi {{count}} log correlati (insieme completo più grande)." - }, - "saved": { - "title": "Salvati", - "empty": "Nessuna ricerca salvata", - "saveCurrent": "Salva ricerca corrente", - "save": "Salva", - "namePlaceholder": "Nome ricerca", - "delete": "Elimina", - "saved": "Salvata “{{name}}”", - "loading": "Caricamento…", - "loadFailed": "Impossibile caricare le ricerche salvate", - "saveFailed": "Impossibile salvare la ricerca", - "deleteFailed": "Impossibile eliminare la ricerca", - "unreadable": "Impossibile leggere quella ricerca salvata" - } - }, - "integrations": { - "title": "Integrazioni", - "searchPlaceholder": "Cerca integrazioni…", - "noMatch": "Nessuna integrazione corrisponde.", - "browseMarketplace": "Sfoglia marketplace", - "loading": "Caricamento integrazioni…", - "addCustom": { - "title": "Aggiungi integrazione personalizzata", - "description": "Crea una nuova fonte personalizzata", - "cta": "Crea" - }, - "tabs": { - "all": "Tutte", - "agents": "Agenti", - "collectors": "Collector", - "cloud": "Cloud", - "custom": "Personalizzata" - }, - "kind": { - "agents & syslog": "Agente", - "device": "Collector", - "antivirus": "Collector", - "other": "Collector", - "custom": "Personalizzata", - "cloud": "Cloud", - "utmstack modules": "Collector" - }, - "status": { - "configured": "Configurata", - "available": "Disponibile" - }, - "card": { - "manage": "Gestisci →", - "setup": "Configura →", - "eventsPerSec": "{{rate}} e/s", - "enabled": "Attivato", - "setupShort": "Configura" - }, - "drawer": { - "manage": "Gestisci", - "openDashboard": "Apri dashboard", - "viewEvents": "Visualizza eventi", - "documentation": "Documentazione", - "getInstallCmd": "Ottieni comando di installazione", - "setupCollector": "Configura collector", - "connect": "Connetti", - "configureCustom": "Configura fonte personalizzata", - "eventsRate": "{{rate}} eventi/s · {{count}} in 24h", - "manageRules": "Regole", - "manageFilters": "Filtri" - }, - "setup": { - "agent": { - "howItWorksTitle": "Come funziona", - "howItWorksBody": "L'agente {{name}} è un piccolo daemon che viene eseguito sull'host e inoltra gli eventi locali a UTMStack su una connessione TLS autenticata. Si aggiorna automaticamente e segnala il suo stato di salute.", - "installTitle": "Installa su {{name}}", - "installHint": "Esegui questo comando su ogni host {{name}} che desideri monitorare. Il token codifica già il tuo workspace attuale.", - "afterTitle": "Cosa vedrai dopo l'installazione", - "after1": "L'host appare sotto Origini dati entro ~60 secondi dall'avvio dell'agente.", - "after2": "La telemetria inizia a fluire in Log Explorer, limitata al tuo workspace.", - "after3": "L'agente auto-segnala lo stato di CPU/memoria/disco a UTMStack.", - "actionLabel": "Azione", - "platformLabel": "Piattaforma", - "optionsLabel": "Opzioni", - "skipCertValidation": "Salta la convalida del certificato TLS (server autofirmato)", - "noRemoteControl": "Disabilita l'esecuzione remota di comandi su questo host", - "loadingToken": "Caricamento token…", - "actions": { - "install": "Installa", - "uninstall": "Disinstalla" - }, - "prereqTitle": "Requisiti pre-installazione", - "prereqBody": "L'agente UTMStack comunica con il server tramite le seguenti porte. Assicurarsi che siano aperte tra l'host e UTMStack prima di procedere con l'installazione:", - "sensitiveWarning": "Il comando seguente contiene un token di registrazione sensibile — non condividerlo.", - "uninstall": { - "title": "Disinstalla l'agente", - "body": "Eseguire questo comando sull'host per arrestare e rimuovere l'agente UTMStack e i relativi servizi. Utilizza la piattaforma selezionata in precedenza." - }, - "macCompat": "Richiede macOS 11 (Big Sur) o versione successiva su Apple Silicon (M1/M2/M3 o più recente). I Mac basati su Intel non sono supportati." - }, - "collector": { - "howItWorksTitle": "Come funziona", - "howItWorksBody": "{{name}} non esegue un agente UTMStack. Invece, installi il collector UTMStack da qualche parte sulla rete che sia il tuo dispositivo {{name}} che UTMStack possono raggiungere. {{name}} invia syslog al collector, il collector analizza, normalizza e inoltra gli eventi a UTMStack.", - "step1Title": "1 · Installa il collector UTMStack", - "step1Hint": "Esegui su un host Linux con accesso di rete dal dispositivo {{name}}.", - "step2Title": "2 · Configura {{name}} per inviare syslog", - "step2Hint": "Sul dispositivo {{name}}, punta l'inoltro syslog all'indirizzo del collector su {{port}}.", - "vendorDocs": "Vedi istruzioni specifiche del fornitore", - "step3Title": "3 · Verifica", - "step3Body": "Entro pochi minuti dovresti vedere gli eventi di {{name}} sotto source: {{source}} in Log Explorer e una nuova voce in Origini dati.", - "endpoint": { - "title": "Dettagli di connessione", - "hint": "Configurare {{name}} per inoltrare i log al Collector utilizzando l'host e la porta indicati di seguito." - }, - "syslog": { - "sections": { - "sendLogs": { - "title": "1 · Invia log a UTMStack", - "body": "Configurare il dispositivo per inviare messaggi syslog tramite UDP (514) o TCP (514) all'agente UTMStack." - }, - "enableCollector": { - "title": "2 · Abilita il collector syslog", - "body": "Abilitare il log collector e l'integrazione syslog nel file di configurazione in cui è installato l'agente UTMStack." - }, - "activate": { - "title": "3 · Attiva", - "body": "Attivare il modulo UTMStack affinché gli eventi inizino a fluire nel Log Explorer." - } - } - }, - "netflow": { - "source": "Dispositivo di rete", - "step1": { - "title": "Abilita il listener NetFlow sul Collector", - "body": "Sull'host in cui è installato il Collector, eseguire questo comando per aprire il collector NetFlow sulla porta 2055:", - "note": "NetFlow utilizza solo UDP — TCP e TLS non sono supportati per questo protocollo." - }, - "step2": { - "title": "Configura il dispositivo per esportare NetFlow", - "body": "Puntare l'esportazione NetFlow del router o firewall verso l'host Collector sulla porta {{port}} UDP. L'esempio seguente è per Cisco IOS — consultare la documentazione del fornitore per altre piattaforme:", - "note": "Sostituire con il nome dell'interfaccia su cui monitorare il traffico (es. GigabitEthernet0/0). Applicare ingress/egress su ogni interfaccia pertinente." - } - }, - "cisco": { - "source": "Cisco ASA", - "step1": { - "title": "Abilita il listener Cisco ASA sul Collector", - "body": "Sull'host in cui è installato il Collector, eseguire questo comando per aprire il listener di log Cisco ASA:", - "note": "Per utilizzare TCP al posto di UDP, sostituire udp con tcp nel comando precedente." - }, - "step2": { - "title": "Configura Cisco ASA per l'inoltro dei log", - "body": "Sul Cisco ASA, abilitare syslog e puntarlo verso l'host Collector sulla porta {{port}}. Eseguire questi comandi in modalità EXEC privilegiata (sostituire con il nome dell'interfaccia interna o di gestione):" - } - }, - "ciscoSwitch": { - "source": "Cisco Switch", - "step1": { - "title": "Abilita il listener Cisco Switch sul Collector", - "body": "Sull'host in cui è installato il Collector, eseguire questo comando per aprire il listener di log Cisco Switch:", - "note": "Per utilizzare TCP al posto di UDP, sostituire udp con tcp nel comando precedente." - }, - "step2": { - "title": "Configura lo switch per l'inoltro dei log", - "body": "In modalità EXEC privilegiata sul Cisco switch, abilitare syslog e puntarlo verso l'host Collector sulla porta {{port}}:" - } - }, - "ciscoMeraki": { - "source": "Cisco Meraki", - "step1": { - "title": "Abilita il listener Cisco Meraki sul Collector", - "body": "Sull'host in cui è installato il Collector, eseguire questo comando per aprire il listener di log Cisco Meraki:", - "note": "Per utilizzare TCP al posto di UDP, sostituire udp con tcp nel comando precedente." - }, - "step2": { - "title": "Configura Meraki per l'inoltro dei log", - "body": "Nel Meraki Dashboard, andare su Network-wide → Configure → General, scorrere fino alla sezione Reporting e aggiungere un server syslog con l'IP del Collector e la porta {{port}}. Selezionare tutti i ruoli che si desidera inoltrare." - } - }, - "ciscoFirepower": { - "source": "Cisco Firepower", - "step1": { - "title": "Abilita il listener Cisco Firepower sul Collector", - "body": "Sull'host in cui è installato il Collector, eseguire questo comando per aprire il listener di log Cisco Firepower:", - "note": "Per utilizzare TCP al posto di UDP, sostituire udp con tcp nel comando precedente." - }, - "step2": { - "title": "Configura Firepower per l'inoltro dei log", - "body": "In Firepower Management Center (FMC), andare su Devices → Platform Settings, modificare o creare un criterio e navigare fino a Syslog → Syslog Servers. Aggiungere l'IP del Collector con la porta {{port}} (UDP), quindi assegnare il criterio ai dispositivi e distribuire." - } - }, - "vmware": { - "source": "VMware ESXi", - "step1": { - "title": "Abilita il listener VMware sul Collector", - "body": "Sull'host in cui è installato il Collector, eseguire questo comando per aprire il listener syslog VMware ESXi. ESXi trasmette tramite TCP:", - "note": "Per un canale cifrato, utilizzare tls al posto di tcp (caricare prima i certificati sul Collector)." - }, - "step2": { - "title": "Punta il syslog ESXi verso il Collector", - "body": "Aprire una sessione SSH/ESXi Shell sull'host (o usare il vSphere Client: Host → Configure → Advanced System Settings → Syslog.global.logHost). Impostare il loghost remoto su {{host}}:{{port}} e ricaricare la configurazione:", - "note": "Su vSphere è possibile impostare Syslog.global.logHost sullo stesso valore tcp://host:port invece di eseguire esxcli." - }, - "step3": { - "title": "Apri il firewall ESXi per syslog", - "body": "Consentire il syslog in uscita attraverso il firewall ESXi in modo che l'host possa raggiungere il Collector:" - } - }, - "as400": { - "intro": { - "title": "Come funziona", - "body": "L'AS/400 Collector è un servizio Linux che si connette direttamente ai sistemi AS/400 (IBM i) e recupera le voci del registro di sicurezza, trasmettendole in modo sicuro a UTMStack per la correlazione e gli avvisi.", - "note": "Nulla viene installato sull'AS/400 stesso — il Collector viene eseguito su un host Linux con accesso di rete ai sistemi AS/400.", - "diagram": { - "source": "i tuoi journal", - "edge1": "journal", - "collector": "AS/400 Collector", - "collectorSub": "recupera dall'AS/400", - "edge2": "sicuro", - "utmstackSub": "avvisi & correlazione" - } - }, - "install": { - "title": "Installa l'AS/400 Collector", - "body": "Eseguire questo comando su un host Linux che possa raggiungere sia UTMStack che i sistemi AS/400 tramite la rete.", - "reuse": "Hai già installato l'AS/400 Collector? Salta questo passaggio — aggiungi semplicemente i tuoi server al file di configurazione nel passaggio successivo." - }, - "configure": { - "title": "Aggiungi i tuoi server AS/400", - "body": "Modificare as400-config.yaml nella directory di installazione del collector e aggiungere ogni sistema AS/400 che si desidera monitorare:", - "note": "È possibile elencare più server. Il collector monitora questo file e si ricarica automaticamente al salvataggio — non è necessario riavviarlo." - }, - "journal": { - "title": "Abilita il journaling di audit sull'AS/400", - "body": "Su ogni sistema AS/400, assicurarsi che il journal di audit QAUDJRN sia attivo. Fare riferimento alla documentazione IBM per i passaggi esatti — la procedura varia tra le versioni di IBM i." - }, - "uninstall": { - "title": "Opzionale — Disinstalla il Collector", - "body": "Eseguire questo comando sull'host in cui è installato l'AS/400 Collector per arrestare il servizio e rimuovere tutti i file." - } - }, - "bitdefender": { - "intro": { - "title": "Come funziona", - "body": "UTMStack si connette a Bitdefender GravityZone utilizzando la chiave API per configurare l'Event Push Service. GravityZone invia quindi eventi di sicurezza direttamente a UTMStack per la correlazione e gli avvisi.", - "diagram": { - "source": "eventi endpoint", - "edge": "Event Push Service", - "utmstackSub": "avvisi & correlazione" - }, - "note": "Nessun agente viene installato su GravityZone — UTMStack si registra come destinazione push utilizzando credenziali API di sola lettura." - }, - "whitelist": { - "title": "Aggiungi alla whitelist gli IP di Bitdefender", - "body": "I seguenti indirizzi IP di Bitdefender GravityZone devono essere consentiti attraverso il firewall sulla porta 8000 affinché l'Event Push Service possa raggiungere UTMStack:", - "note": "Aggiungere questi IP al firewall o al gruppo di sicurezza prima di completare la configurazione." - }, - "apiSection": "Ottieni le credenziali API", - "api": { - "myAccount": { - "title": "Apri Il Mio Account", - "body": "Nella console Bitdefender GravityZone, fare clic su My Account." - }, - "accessUrl": { - "title": "Annota l'URL di accesso", - "body": "Scorrere fino alla sezione Control Center API e salvare l'Access URL — verrà inserito nel modulo delle credenziali di seguito. Quindi aprire la sezione della chiave API e fare clic su Add in cima alla tabella." - }, - "createKey": { - "title": "Crea una chiave API", - "body": "Scrivere una descrizione per la chiave API, selezionare l'opzione Event Push Service API e fare clic su Save. Copiare la chiave generata." - } - }, - "companySection": "Ottieni gli ID azienda", - "company": { - "myCompany": { - "title": "Apri La Mia Azienda", - "body": "Nella console GravityZone, fare clic su My Company." - }, - "licensing": { - "title": "Annota gli ID azienda", - "body": "Aprire la sezione Licensing e salvare gli ID azienda che si desidera monitorare — inserirli separati da virgola nel modulo delle credenziali di seguito." - } - }, - "credentials": { - "title": "Inserisci le credenziali", - "body": "Inserire l'Access URL, la chiave API, l'IP pubblico di UTMStack (dove GravityZone invierà gli eventi) e gli ID aziendali da monitorare. UTMStack verifica le credenziali prima del salvataggio." - }, - "fields": { - "accessUrl": { - "label": "URL di accesso GravityZone" - }, - "connectionKey": { - "label": "Chiave API" - }, - "utmPublicIP": { - "label": "IP pubblico UTMStack" - }, - "companyIds": { - "label": "ID aziendali (separati da virgola)" - } - } - }, - "eset": { - "source": "ESET Protect", - "step1": { - "title": "Abilitare il listener ESET sul Collector", - "body": "Sull'host in cui è installato il Collector, eseguire questo comando per aprire il listener syslog di ESET:", - "note": "Per utilizzare TCP invece di UDP, sostituire udp con tcp nel comando precedente." - }, - "console": { - "moreMenu": { - "title": "Aprire il menu More", - "body": "Nella barra laterale della console ESET Protect, fare clic sul menu More." - }, - "serverConfig": { - "title": "Aprire Server settings", - "body": "Nella sezione More, aprire la sezione Server settings (configurazione del server)." - }, - "advanced": { - "title": "Espandere Advanced settings", - "body": "Fare clic su Advanced settings per espandere l'elenco completo delle opzioni di configurazione." - }, - "syslog": { - "title": "Configurare il server Syslog", - "body": "Scorrere fino a Syslog server, abilitare Export logs to Syslog e impostare la destinazione sull'host Collector sulla porta {{port}} (UDP). ESET invia LEEF/syslog, che il Collector acquisisce come tipo di dati antivirus-esmc-eset." - } - } - }, - "kaspersky": { - "source": "Kaspersky Security", - "step1": { - "title": "Abilitare il listener Kaspersky sul Collector", - "body": "Sull'host in cui è installato il Collector, eseguire questo comando per aprire il listener syslog di Kaspersky:", - "note": "Per utilizzare TCP invece di UDP, sostituire udp con tcp nel comando precedente." - }, - "console": { - "consoleSettings": { - "title": "Aprire Console settings → Integration", - "body": "Nella barra laterale di Kaspersky Security Center, aprire Console settings e fare clic sul sottomenu Integration." - }, - "siem": { - "title": "Aprire le impostazioni di integrazione SIEM", - "body": "Nella sezione Integration, selezionare SIEM e fare clic sul collegamento Settings per aprire la configurazione di esportazione." - }, - "configure": { - "title": "Configurare l'esportazione SIEM", - "body": "Abilitare l'esportazione e configurare Kaspersky per inviare gli eventi in formato Splunk (CEF) all'host Collector sulla porta {{port}} (UDP). Il Collector li acquisisce come tipo di dati antivirus-kaspersky." - } - } - }, - "sophos": { - "intro": { - "title": "Sophos Central — API Plugin", - "body": "Sophos Central fornisce API sicure per recuperare dati di eventi e avvisi. UTMStack si connette a queste API per centralizzare il monitoraggio e migliorare la visibilità della sicurezza — nessun agente o collector richiesto.", - "diagram": { - "source": "Sophos Central API", - "edge": "HTTPS API", - "utmstackSub": "Acquisisce e correla" - }, - "note": "UTMStack interroga periodicamente la Sophos Central API. Assicurarsi che le credenziali API create in seguito dispongano di accesso in lettura a eventi e avvisi." - }, - "apiSection": "Generare le credenziali API in Sophos Central", - "steps": { - "apiCredentials": { - "title": "Aprire API Credentials Management", - "body": "In Sophos Central Admin, navigare fino a Global Settings → API Credentials Management." - }, - "addCredential": { - "title": "Creare una nuova credenziale", - "body": "Fare clic su Add Credential. Inserire un Name e una Description, selezionare il Role appropriato, quindi fare clic su Add." - }, - "copyIds": { - "title": "Copiare Client ID e Client Secret", - "body": "Copiare il Client ID e il Client Secret e conservarli in modo sicuro.", - "secretNote": "Il Client Secret viene visualizzato una sola volta. Salvarlo in un luogo sicuro prima di chiudere questa finestra." - } - }, - "credentialsSection": "Connetti a UTMStack", - "credentials": { - "title": "Aggiungere le credenziali Sophos Central", - "body": "Inserire le credenziali appena create. È possibile aggiungere più di un account Sophos facendo clic su Aggiungi gruppo di configurazione." - }, - "fields": { - "clientId": { - "label": "Client ID" - }, - "apiKey": { - "label": "Client Secret / Chiave API" - } - } + "incidents": { + "title": "Incidenti", + "subtitle": "Raggruppa, valuta e risolvi gli alert correlati come incidenti.", + "refresh": "Aggiorna", + "count_one": "{{count}} incidente", + "count_other": "{{count}} incidenti", + "openNow": "aperti ora", + "empty": "Nessun incidente corrispondente.", + "loadError": "Impossibile caricare gli incidenti.", + "retry": "Riprova", + "unassigned": "Non assegnato", + "unknownUser": "Sconosciuto", + "status": { + "open": "Aperto", + "in_review": "In revisione", + "completed": "Completato", + "merged": "Unito" }, - "webroot": { - "sections": { - "login": { - "title": "1 · Accedere alla console di gestione", - "body": "Accedere alla console di gestione Webroot. Si apre nella scheda Sites." - }, - "openSettings": { - "title": "2 · Aprire Settings", - "body": "Fare clic sulla scheda Settings." - }, - "apiAccess": { - "title": "3 · Aprire API Access", - "body": "Dalla scheda Subscriptions, fare clic sulla scheda API Access." - }, - "createCredential": { - "title": "4 · Creare una credenziale client", - "body": "Fare clic su New e compilare Name e Description. Leggere il contratto SecureAnywhere Business Solution e Unity API, quindi fare clic su Create." - }, - "noteClientSecret": { - "title": "5 · Copiare il client ID e il segreto", - "body": "Salvare il Client ID dall'elenco e il Client Secret visualizzato una sola volta. Fare clic su \"I have made note of the client secret\" per confermare." - }, - "fillForm": { - "title": "6 · Compilare il modulo", - "body": "Fornire il client ID e il client secret a UTMStack. Se necessario, è possibile aggiungere più gruppi di configurazione Webroot." - }, - "activate": { - "title": "7 · Attivare", - "body": "Attivare il modulo UTMStack affinché gli eventi Webroot inizino a fluire." - } - } - }, - "sentinelOne": { - "source": "SentinelOne", - "step1": { - "title": "Abilitare il listener SentinelOne sul Collector", - "body": "Sull'host in cui è installato il Collector, eseguire questo comando per aprire il listener syslog di SentinelOne. SentinelOne trasmette CEF via TCP:", - "note": "Per un canale crittografato, utilizzare tls invece di tcp (caricare prima i certificati sul Collector)." - }, - "console": { - "settings": { - "title": "Aprire le impostazioni di SentinelOne", - "body": "Nella barra laterale della console di gestione di SentinelOne, fare clic sul menu Settings." - }, - "syslog": { - "title": "Configurare l'integrazione Syslog", - "body": "Andare su Integrations → Syslog e abilitarlo. Impostare l'host su {{host}} e la porta su {{port}}, mantenere il formato come CEF, fare clic su Test per verificare la connessione, quindi su Save." - } - } - }, - "office365": { - "intro": { - "title": "Come funziona", - "body": "UTMStack si connette a Microsoft 365 tramite un'app Azure AD registrata e interroga periodicamente l'Office 365 Management Activity API per eventi di audit e sicurezza. Nessun agente viene installato nel tenant.", - "diagram": { - "source": "eventi di audit e sicurezza", - "edge": "Management API", - "utmstackSub": "correlazione e avvisi" - }, - "note": "UTMStack richiede accesso API in sola lettura — non vengono richieste autorizzazioni di scrittura." - }, - "appSection": "Registrazione dell'app Azure", - "steps": { - "azurePortal": { - "title": "Aprire Microsoft Entra ID", - "body": "Aprire il Azure Portal (portal.azure.com) e fare clic su Microsoft Entra ID." - }, - "appRegistrations": { - "title": "Andare in App registrations", - "body": "Nel menu a sinistra, fare clic su App registrations." - }, - "registerApp": { - "title": "Registrare una nuova app", - "body": "Fare clic su New registration. Denominarlo UTMStack O365 Agent, selezionare Accounts in this organizational directory only (Single-tenant) e fare clic su Register." - }, - "clientSecret": { - "title": "Creare un client secret", - "body": "Andare su Certificates & Secrets → New client secret. Aggiungere una descrizione, impostare la scadenza su 730 days (24 months) e fare clic su Add.", - "copyNote": "Copiare immediatamente il valore del segreto — viene visualizzato una sola volta e non può essere recuperato in seguito." - }, - "apiPermissions": { - "title": "Aggiungere le autorizzazioni per l'Office 365 Management API", - "body": "Andare su API Permissions → Add a permission e cercare Office 365 Management APIs." - }, - "activityFeed": { - "title": "Concedere le autorizzazioni ActivityFeed", - "body": "Selezionare Application Permissions e aggiungere ActivityFeed.Read e ActivityFeed.ReadDlp. Fare clic su Grant admin consent e confermare." - }, - "graphPermissions": { - "title": "Aggiungere le autorizzazioni Microsoft Graph", - "body": "Tornando su Add a permission, fare clic su Microsoft Graph." - }, - "delegatedPermissions": { - "title": "Aggiungere le autorizzazioni delegate SecurityAlert", - "body": "Selezionare Delegated Permissions e aggiungere SecurityAlert.Read.All e SecurityAlert.ReadWrite.All. Fare clic su Grant admin consent e confermare." - }, - "appPermissions": { - "title": "Aggiungere le autorizzazioni applicazione SecurityAlert", - "body": "Selezionare Application Permissions e aggiungere SecurityAlert.Read.All e SecurityAlert.ReadWrite.All. Fare clic su Grant admin consent e confermare." - }, - "noteIds": { - "title": "Copiare gli ID dell'app", - "body": "Andare nella sezione Overview dell'app e copiare l'Application (client) ID e il Directory (tenant) ID. È necessario anche il valore segreto copiato al passaggio 4." - } - }, - "credentialsSection": "Credenziali", - "credentials": { - "title": "Connettere il tenant Microsoft 365", - "body": "Inserire i dettagli dei passaggi precedenti. UTMStack verifica le credenziali prima del salvataggio. È possibile aggiungere più gruppi di configurazione." - }, - "fields": { - "tenantId": { - "label": "Tenant ID (Directory ID)" - }, - "clientId": { - "label": "Client ID (Application ID)" - }, - "clientSecret": { - "label": "Client Secret" - }, - "cloudEnv": { - "label": "Ambiente cloud (facoltativo)", - "hint": "Commercial (default), GCC, GCCHigh, or DoD" - } - } - }, - "github": { - "source": "GitHub", - "step1": { - "title": "Abilita il listener webhook di GitHub sul Collector", - "body": "Sull'host in cui è installato il Collector, esegui questo comando per aprire il listener webhook HTTPS per GitHub:", - "tokenNote": "Il terminale stamperà un token segreto — copialo immediatamente. Non verrà mostrato di nuovo." - }, - "certWarning": { - "title": "GitHub richiede un certificato TLS firmato da una CA", - "body": "GitHub recapita i webhook solo agli endpoint HTTPS con un certificato emesso da una CA pubblica (i certificati autofirmati vengono rifiutati). Assicurati che l'host Collector disponga di un certificato di dominio valido prima di registrare il webhook." - }, - "step2": { - "title": "Registra il webhook in GitHub", - "body": "Nel tuo repository o nella tua organizzazione, vai su Settings → Webhooks → Add webhook e compila il modulo:", - "payloadUrl": "URL del payload", - "contentType": "Tipo di contenuto", - "secret": "Segreto", - "secretHint": "Incolla il token stampato dal Collector nel passaggio precedente.", - "events": "Quali eventi", - "eventsHint": "Invia tutto — oppure seleziona tipi di evento specifici." - } - }, - "salesforce": { - "sections": { - "openSetup": { - "title": "1 · Apri Setup", - "body": "Vai a Setup e seleziona \"Setup for the current app\" in alto a destra dello schermo." - }, - "appManager": { - "title": "2 · Apri App Manager", - "body": "Digita \"App Manager\" nella casella di ricerca rapida e seleziona App Manager." - }, - "newConnectedApp": { - "title": "3 · Crea una nuova Connected App", - "body": "Nella schermata Lightning Experience App Manager, fai clic su \"New Connected App\" e compila i campi." - }, - "oauthSettings": { - "title": "4 · Abilita le impostazioni OAuth", - "body": "Nella sezione \"API (Enable OAuth Settings)\", spunta \"Enable OAuth Settings\" e usa https://login.salesforce.com/services/oauth2/success come Callback URL." - }, - "oauthScopes": { - "title": "5 · Aggiungi gli scope OAuth", - "body": "Seleziona \"Access Connect REST API resources (chatter_api)\" sotto Selected OAuth Scopes." - }, - "save": { - "title": "6 · Salva", - "body": "Salva le modifiche e seleziona Continue nella schermata successiva." - }, - "manageConsumer": { - "title": "7 · Apri Manage Consumer Details", - "body": "All'interno della tua Connected App, vai su \"API (Enable OAuth Settings)\" e fai clic su \"Manage Consumer Details\" accanto a Consumer Key e Secret." - }, - "copyCredentials": { - "title": "8 · Copia la consumer key e il secret", - "body": "Verifica la tua identità. Consumer Key e Consumer Secret compaiono sotto \"Consumer Details\". Copiali entrambi con il pulsante Copy." - }, - "fillForm": { - "title": "9 · Compila il modulo", - "body": "Fornisci a UTMStack la Consumer Key, il Consumer Secret, il nome utente e la password Salesforce." - }, - "activate": { - "title": "10 · Attiva", - "body": "Attiva il modulo UTMStack per avviare il flusso degli eventi Salesforce." - } - } + "sev": { + "high": "Alta", + "medium": "Media", + "low": "Bassa", + "unknown": "Non valutata" }, - "iis": { - "sections": { - "enableModule": { - "title": "1 · Abilita il modulo IIS Filebeat", - "body": "Sull'host dell'agente UTMStack, esegui:\ncd \"C:\\Program Files\\UTMStack\\UTMStack Agent\\beats\\filebeat\\\" && filebeat modules enable iis" - }, - "configureModule": { - "title": "2 · Configura il modulo IIS", - "body": "Modifica C:\\Program Files\\UTMStack\\UTMStack Agent\\beats\\filebeat\\modules.d\\iis.yml come mostrato di seguito per puntare alle directory di log IIS che vuoi inviare." - }, - "activate": { - "title": "3 · Attiva", - "body": "Attiva il modulo UTMStack per avviare il flusso degli eventi IIS." - } - } + "toolbar": { + "search": "Cerca incidenti…", + "create": "Crea incidente", + "allSeverities": "Tutte le gravità", + "export": "Esporta CSV" }, - "filebeat": { - "sections": { - "installRsyslog": { - "title": "1 · Installa rsyslog", - "body": "Assicurati che rsyslog sia installato sull'host. Usa il gestore pacchetti della tua distribuzione (apt, dnf, yum)." - }, - "configureRsyslog": { - "title": "2 · Configura rsyslog per inviare a UTMStack", - "body": "Modifica /etc/rsyslog.conf (o un file sotto /etc/rsyslog.d/) e aggiungi una regola di inoltro che punti all'agente UTMStack tramite UDP o TCP sulla porta 514." - }, - "restartRsyslog": { - "title": "3 · Riavvia rsyslog", - "body": "Riavvia il servizio rsyslog: sudo systemctl restart rsyslog" - }, - "enableCollector": { - "title": "4 · Abilita il raccoglitore di log Linux", - "body": "Abilita il raccoglitore di log e l'integrazione Linux Logs nel file di configurazione in cui è installato l'agente UTMStack." - } - } + "statusTabs": { + "all": "Tutti" }, - "json": { - "sections": { - "overview": { - "title": "1 · Usa l'endpoint di ingestione HTTP/JSON", - "body": "UTMStack accetta eventi JSON arbitrari tramite HTTPS. Invia una richiesta POST con un elenco di eventi; UTMStack li analizza e li instrada tramite il parser configurato." - }, - "auth": { - "title": "2 · Autentica con un token di federazione", - "body": "Ottieni un token di federazione da Settings → Connection Key e invialo come token Bearer nell'intestazione Authorization." - } - }, - "endpoint": { - "title": "Endpoint di ingestione JSON", - "hint": "Usa questo formato di richiesta dalla tua applicazione o da un cron job. Il token è la chiave di federazione da Settings → Connection Key." - } - }, - "ldap": { - "sections": { - "openServerManager": { - "title": "1 · Apri Server Manager", - "body": "Nel controller di dominio AD, apri Server Manager." - }, - "addRoles": { - "title": "2 · Aggiungi ruoli e funzionalità", - "body": "Scegli \"Add roles and features\" dal menu Manage." - }, - "selectCertServices": { - "title": "3 · Seleziona Active Directory Certificate Services", - "body": "Nella fase Server Roles, seleziona Active Directory Certificate Services." - }, - "installServices": { - "title": "4 · Installa il servizio ruolo Certificate Authority", - "body": "Nella fase Role Services, seleziona Certificate Authority e completa la procedura guidata." - }, - "configureAdCs": { - "title": "5 · Configura AD CS", - "body": "Dopo l'installazione, fai clic sulla notifica per configurare AD CS e scegli Certificate Authority come servizio ruolo da configurare." - }, - "pickCaType": { - "title": "6 · Scegli il tipo di CA", - "body": "Scegli Enterprise CA → Root CA → Create a new private key." - }, - "setValidity": { - "title": "7 · Imposta il periodo di validità del certificato", - "body": "Imposta un periodo di validità adeguato alla tua organizzazione (5 anni è tipico)." - }, - "confirm": { - "title": "8 · Conferma e installa", - "body": "Rivedi le impostazioni e fai clic su Configure per terminare." - }, - "restart": { - "title": "9 · Riavvia il controller di dominio", - "body": "Riavvia il controller di dominio affinché LDAPS diventi disponibile su TCP 636." - }, - "activate": { - "title": "10 · Attiva", - "body": "Attiva il modulo UTMStack per avviare il flusso degli eventi di audit AD." - } - } - }, - "oracle": { - "source": "Server Oracle DB", - "step1": { - "title": "Abilita l'integrazione Oracle sul Collector", - "body": "Sul server in cui è installato il Collector, esegui il seguente comando per avviare l'ascolto dei log Oracle:", - "note": "Il Collector inizierà a ricevere eventi syslog da Oracle sulla porta 7021." - }, - "step2": { - "title": "Configura rsyslog sul server Oracle", - "body": "Crea il file di configurazione rsyslog:", - "editBody": "Apri il file con l'editor preferito e aggiungi la seguente configurazione. Sostituisci BASEDIR con il percorso di installazione di Oracle (es. /u01/app/oracle) e con l'indirizzo IP o il nome host del Collector:", - "note": "Usa @@:7021 invece di @ se preferisci la consegna via TCP." - }, - "step3": { - "title": "Riavvia rsyslog", - "body": "Applica la nuova configurazione riavviando il servizio rsyslog:" - }, - "step4": { - "title": "Convalida la configurazione", - "body": "Invia messaggi di log di test per verificare che UTMStack stia ricevendo eventi da tutte e tre le sorgenti di log Oracle:", - "note": "Apri Log Explorer e cerca il testo del messaggio di test sopra per confermare l'arrivo degli eventi." - } - }, - "vulnerabilities": { - "sections": { - "overview": { - "title": "1 · Informazioni sullo scanner delle vulnerabilità", - "body": "Il modulo vulnerabilità di UTMStack esegue la scansione degli asset scoperti tramite il modulo Asset Management e ne confronta l'impronta con il database CVE." - }, - "scope": { - "title": "2 · Definisci l'ambito di scansione", - "body": "Usa il modulo Asset Management per registrare gli host che vuoi sottoporre a scansione. Lo scanner delle vulnerabilità verrà eseguito periodicamente su di essi." - }, - "activate": { - "title": "3 · Attiva", - "body": "Attiva il modulo UTMStack per avviare la scansione." - } - } + "filters": { + "add": "Aggiungi filtro", + "clearAll": "Cancella tutto", + "filterValues": "Filtra valori…", + "loadingValues": "Caricamento valori…", + "noValues": "Nessun valore trovato.", + "pickValue": "Scegli un valore per aggiungere il filtro.", + "empty": "(vuoto)", + "cancel": "Annulla", + "addBtn": "Aggiungi" }, - "assetScanner": { - "sections": { - "overview": { - "title": "1 · Informazioni su Asset Management", - "body": "Il modulo Asset Management scopre e inventaria host, software e servizi nella rete." - }, - "agentRequirement": { - "title": "2 · Requisito agente", - "body": "Il rilevamento degli asset utilizza agenti UTMStack in esecuzione su host Linux, Windows o macOS. Installa l'agente sui sistemi che desideri inventariare." - }, - "activate": { - "title": "3 · Attiva", - "body": "Attiva il modulo UTMStack per avviare il rilevamento degli asset." - } - } + "ops": { + "IS": "è" }, - "fileIntegrity": { - "sections": { - "enableAuditPolicy": { - "title": "1 · Abilita il controllo dell'accesso agli oggetti", - "body": "Sull'host Windows, apri Criteri di gruppo → Configurazione computer → Impostazioni di Windows → Impostazioni di sicurezza → Configurazione avanzata criteri di controllo → Accesso agli oggetti e abilita \"Controlla file system\"." - }, - "configureFolderAuditing": { - "title": "2 · Configura il controllo delle cartelle", - "body": "Per ogni cartella che desideri monitorare, apri Proprietà → Sicurezza → Avanzate → Controllo e aggiungi una voce di controllo per le entità e i tipi di accesso desiderati." - }, - "verifyEvents": { - "title": "3 · Verifica la presenza degli eventi nel registro di sicurezza", - "body": "Apri il Visualizzatore eventi e verifica che gli eventi 4663/4670 vengano generati quando si accede agli oggetti controllati." - }, - "activate": { - "title": "4 · Attiva", - "body": "Attiva il modulo UTMStack affinché gli eventi di integrità dei file inizino a fluire." - } - } + "layout": { + "table": "Tabella", + "board": "Bacheca" }, - "socAi": { - "sections": { - "overview": { - "title": "1 · Informazioni su SOC AI", - "body": "SOC AI potenzia UTMStack con un analista basato su LLM che sintetizza gli avvisi e suggerisce i passi successivi. Opera tramite il provider che configuri." - }, - "chooseProvider": { - "title": "2 · Scegli un provider", - "body": "Seleziona un provider — OpenAI, Anthropic, Azure OpenAI, Google Gemini, Ollama, Mistral, DeepSeek, Groq o un endpoint personalizzato compatibile con OpenAI." - }, - "configureCredentials": { - "title": "3 · Configura le credenziali", - "body": "Fornisci la chiave API e, dove applicabile, il nome del modello e l'URL dell'endpoint." - }, - "activate": { - "title": "4 · Attiva", - "body": "Attiva il modulo UTMStack affinché SOC AI inizi a elaborare gli avvisi." - } - } - }, - "utmstack": { - "intro": { - "title": "Come funziona", - "body": "Questa integrazione monitora autonomamente il tuo deployment UTMStack. Un collector leggero installato sull'host UTMStack segue i log dei container Docker della piattaforma e li invia nuovamente a UTMStack per la correlazione e la generazione di avvisi.", - "diagram": { - "source": "Log Docker", - "sourceSub": "Container UTMStack", - "edge1": "tail", - "collector": "Collector", - "collectorSub": "sull'host", - "edge2": "invia", - "utmstackSub": "Correla e genera avvisi" - } - }, - "requirements": { - "title": "Disponibile solo sull'host UTMStack", - "body": "Questa integrazione può essere installata solo su un'istanza UTMStack che esegue Ubuntu o una distribuzione della famiglia Red Hat. Installa il collector direttamente sul server UTMStack." - }, - "install": { - "title": "Installa il collector", - "body": "Sull'host UTMStack, seleziona il sistema operativo ed esegui il comando seguente per scaricare e installare il collector di auto-monitoraggio:", - "sensitiveWarning": "Questo comando contiene un token di connessione sensibile. Trattalo come una password e non condividerlo." - }, - "after": { - "title": "Cosa vedrai dopo l'installazione", - "item1": "Il collector si registra e appare nella sezione Sorgenti dati.", - "item2": "I log dei container UTMStack iniziano a fluire entro un minuto.", - "item3": "Gli eventi diventano ricercabili in Log Explorer con il tipo di dato utmstack." - }, - "uninstall": { - "title": "Disinstalla il collector", - "body": "Per rimuovere il collector di auto-monitoraggio dall'host UTMStack, esegui:" - } - }, - "windowsFaa": { - "sections": { - "enableAuditPolicy": { - "title": "1 · Abilita il controllo dell'accesso agli oggetti", - "body": "Sull'host Windows, apri Criteri di gruppo → Configurazione computer → Impostazioni di Windows → Impostazioni di sicurezza → Configurazione avanzata criteri di controllo → Accesso agli oggetti e abilita \"Controlla file system\"." - }, - "configureFolderAuditing": { - "title": "2 · Configura il controllo delle cartelle", - "body": "Per ogni cartella che desideri monitorare, apri Proprietà → Sicurezza → Avanzate → Controllo e aggiungi una voce di controllo per le entità e i tipi di accesso desiderati." - }, - "activate": { - "title": "3 · Attiva", - "body": "Attiva il modulo UTMStack affinché gli eventi di attività sui file inizino a fluire." - } - } + "table": { + "name": "Incidente", + "status": "Stato", + "severity": "Severità", + "assignee": "Assegnato", + "alerts": "Alert", + "created": "Creato" }, - "awsBeanstalk": { - "sections": { - "openConsole": { - "title": "1 · Apri la console Elastic Beanstalk", - "body": "Nella console AWS, apri Elastic Beanstalk." - }, - "environment": { - "title": "2 · Apri la pagina di gestione dell'ambiente", - "body": "Accedi alla pagina di gestione dell'ambiente che desideri monitorare." - }, - "configuration": { - "title": "3 · Apri Configurazione", - "body": "Seleziona Configurazione." - }, - "software": { - "title": "4 · Modifica la configurazione Software", - "body": "Nella categoria di configurazione Software, seleziona Modifica." - }, - "s3LogStorage": { - "title": "5 · Abilita l'archiviazione log su S3", - "body": "Nella sezione Archiviazione log S3, seleziona Ruota log per caricare i log ruotati su Amazon S3." - }, - "cloudwatchStreaming": { - "title": "6 · Abilita lo streaming CloudWatch Logs", - "body": "Nella sezione Streaming log istanza su CloudWatch Logs, abilita lo streaming, imposta il periodo di conservazione e scegli se caricare i log esistenti." - }, - "activate": { - "title": "7 · Attiva", - "body": "Attiva il modulo UTMStack affinché gli eventi di Beanstalk inizino a fluire." + "drawer": { + "created": "Creato {{date}}", + "alertsCount": "{{count}} alert", + "solutionPlaceholder": "Risoluzione / note di rimedio…", + "solutionHint": "Salvato quando l’incidente passa a Completato.", + "tabs": { + "overview": "Panoramica", + "alerts": "Alert", + "notes": "Note", + "history": "Cronologia" + }, + "section": { + "description": "Descrizione", + "solution": "Soluzione", + "details": "Dettagli" + }, + "details": { + "id": "ID", + "status": "Stato", + "severity": "Severità", + "assignee": "Assegnato", + "created": "Creato", + "alerts": "Alert collegati" } - } }, - "awsFargate": { - "sections": { - "taskDefinition": { - "title": "1 · Aggiorna la definizione del task", - "body": "Nella definizione del task Fargate, imposta il logDriver su \"awslogs\" e definisci il nome del gruppo di log." - }, - "cloudwatchLogs": { - "title": "2 · Verifica che CloudWatch Logs stia ricevendo i log", - "body": "Apri la console CloudWatch Logs e verifica che il gruppo di log venga popolato quando i task sono in esecuzione." - }, - "iamPrerequisite": { - "title": "3 · Prerequisito utente IAM", - "body": "Questa integrazione condivide le credenziali con il modulo AWS IAM User — assicurati che sia configurato con CloudWatchLogsReadOnlyAccess." - }, - "activate": { - "title": "4 · Attiva", - "body": "Attiva il modulo UTMStack affinché gli eventi di Fargate inizino a fluire." - } - } + "alerts": { + "empty": "Nessun alert collegato a questo incidente.", + "remove": "Scollega alert", + "removeConfirm": "Scollegare “{{name}}” da questo incidente?", + "removed": "Alert scollegato", + "removeError": "Impossibile scollegare l’alert", + "loadingAlert": "Caricamento avviso…", + "alertGone": "Questo avviso non è più nell'archivio — la conservazione potrebbe averlo rimosso.", + "alertFailed": "Impossibile caricare l'avviso.", + "openInAlerts": "Apri in Avvisi" }, - "awsIamUser": { - "sections": { - "iamConsole": { - "title": "1 · Apri la console IAM", - "body": "Nella console AWS, vai su IAM → Utenti → Aggiungi utenti." - }, - "createUser": { - "title": "2 · Crea l'utente", - "body": "Scegli un nome utente (ad es. utmstack-ingest). Seleziona l'accesso programmatico." - }, - "programmaticAccess": { - "title": "3 · Imposta il tipo di credenziale", - "body": "Seleziona \"Chiave di accesso — Accesso programmatico\"." - }, - "attachPolicy": { - "title": "4 · Associa la policy di lettura CloudWatch", - "body": "Associa la policy gestita da AWS CloudWatchLogsReadOnlyAccess." - }, - "review": { - "title": "5 · Verifica l'utente", - "body": "Verifica i dettagli dell'utente e clicca su Crea utente." - }, - "copyKeys": { - "title": "6 · Copia l'ID chiave di accesso e il segreto", - "body": "Copia l'ID chiave di accesso e la Chiave di accesso segreta — il segreto viene mostrato una sola volta." - }, - "createLogGroup": { - "title": "7 · Crea un gruppo di log CloudWatch", - "body": "In CloudWatch → Gruppi di log, crea un gruppo di log denominato \"utmstack\" — le altre integrazioni AWS lo utilizzeranno come destinazione." - }, - "fillForm": { - "title": "8 · Compila il modulo", - "body": "Fornisci a UTMStack la chiave di accesso, il segreto, la regione predefinita e il nome del gruppo di log (ad es. \"utmstack\")." - }, - "activate": { - "title": "9 · Attiva", - "body": "Attiva il modulo UTMStack affinché gli eventi AWS inizino a fluire." - } - } + "notes": { + "empty": "Ancora nessuna nota.", + "add": "Aggiungi nota", + "addError": "Impossibile aggiungere la nota", + "placeholder": "Scrivi una nota…" }, - "awsLambda": { - "sections": { - "iamPrerequisite": { - "title": "1 · Prerequisito utente IAM", - "body": "Lambda si basa sul modulo AWS IAM User — assicurati che tale integrazione sia configurata in anticipo con CloudWatchLogsReadOnlyAccess." - }, - "cloudwatchStream": { - "title": "2 · Lambda invia già dati in streaming a CloudWatch Logs", - "body": "AWS Lambda pubblica automaticamente i log di esecuzione su CloudWatch Logs in /aws/lambda/. UTMStack acquisisce i dati dal gruppo di log configurato durante la configurazione dell'utente IAM." - }, - "activate": { - "title": "3 · Attiva", - "body": "Attiva il modulo UTMStack affinché gli eventi Lambda inizino a fluire." - } - } + "history": { + "empty": "Ancora nessuna cronologia." }, - "awsSqlServer": { - "sections": { - "openRds": { - "title": "1 · Apri la console Amazon RDS", - "body": "Apri https://console.aws.amazon.com/rds/." - }, - "pickDb": { - "title": "2 · Seleziona l'istanza DB", - "body": "Nel pannello di navigazione, seleziona Database e scegli l'istanza DB che desideri monitorare." - }, - "modify": { - "title": "3 · Modifica l'istanza", - "body": "Seleziona Modifica." - }, - "logExports": { - "title": "4 · Abilita l'esportazione dei log", - "body": "Nella sezione Esportazioni log, seleziona Log degli errori e Log dell'agente per pubblicarli su CloudWatch Logs." - }, - "apply": { - "title": "5 · Applica le modifiche", - "body": "Scegli Continua, poi Modifica istanza DB nella pagina di riepilogo." - }, - "activate": { - "title": "6 · Attiva", - "body": "Attiva il modulo UTMStack affinché gli eventi SQL Server inizino a fluire." - } - } + "toast": { + "statusChanged": "Stato incidente aggiornato", + "statusError": "Impossibile cambiare lo stato", + "exportFailed": "Impossibile esportare il CSV" }, - "awsPostgresql": { - "sections": { - "openRds": { - "title": "1 · Apri la console Amazon RDS", - "body": "Apri https://console.aws.amazon.com/rds/." - }, - "pickDb": { - "title": "2 · Seleziona l'istanza DB", - "body": "Nel pannello di navigazione, scegli Database e seleziona l'istanza DB che vuoi modificare." - }, - "logExports": { - "title": "3 · Abilita le esportazioni log", - "body": "Nella sezione Esportazioni log, scegli il log PostgreSQL da pubblicare su CloudWatch Logs." - }, - "apply": { - "title": "4 · Applica le modifiche", - "body": "Scegli Continua, poi Modifica istanza DB nella pagina di riepilogo." - }, - "activate": { - "title": "5 · Attiva", - "body": "Attiva il modulo UTMStack affinché gli eventi PostgreSQL inizino a fluire." - } - } + "assign": { + "assign": "Assegna", + "search": "Cerca utenti…", + "unassign": "Rimuovi assegnazione", + "noUsers": "Nessun utente", + "assigned": "Assegnato a {{user}}", + "unassigned": "Incidente non assegnato", + "error": "Impossibile cambiare l’assegnatario", + "custom": "Assegna personalizzato", + "customPlaceholder": "Inserisci un login…" }, - "awsTrafficMirror": { - "sections": { - "createTarget": { - "title": "1 · Crea un target di mirroring del traffico", - "body": "Nella console VPC, crea un Traffic Mirror Target che punta all'interfaccia di rete della VM dell'agente UTMStack." - }, - "createFilter": { - "title": "2 · Crea un filtro di mirroring del traffico", - "body": "Crea un Traffic Mirror Filter e aggiungi regole in entrata/uscita per i protocolli da mirrorare (ad es. tutto TCP, tutto UDP)." - }, - "createSession": { - "title": "3 · Crea una sessione di mirroring del traffico", - "body": "Crea una Traffic Mirror Session che associa ciascuna interfaccia di rete sorgente al target e al filtro creati." - }, - "iamPrerequisite": { - "title": "4 · Prerequisito utente IAM", - "body": "Assicurati che anche il modulo AWS IAM User sia configurato, in modo che UTMStack possa leggere i log di flusso VPC se necessario." - }, - "activate": { - "title": "5 · Attiva", - "body": "Attiva il modulo UTMStack affinché il traffico mirrorato inizi ad essere analizzato." - } - } - }, - "forwarder": { - "intro": { - "title": "Come funziona", - "body": "I log fluiscono da {{source}} al UTMStack Collector, che li trasmette in modo sicuro a UTMStack per la correlazione e gli avvisi. Non viene installato nulla su {{source}} — è sufficiente che il Collector sia in esecuzione su un host della tua rete." - }, - "diagram": { - "sourceSub": "i tuoi log", - "forwarder": "Collector", - "forwarderSub": "in ascolto su {{port}}", - "utmstack": "UTMStack", - "utmstackSub": "avvisi e correlazione", - "flow1": "log", - "flow2": "sicuro" - }, - "noInstall": "Non viene installato nulla su {{source}} — è sufficiente reindirizzare i log al Collector.", - "install": { - "title": "Installa il UTMStack Collector", - "body": "Il Collector è un servizio Linux che riceve i log dai tuoi dispositivi e li invia a UTMStack. Un singolo Collector gestisce più integrazioni contemporaneamente.", - "reuse": "Hai già un Collector in esecuzione? Salta questo passaggio — punta {{source}} su quello esistente usando l'host e la porta indicati di seguito." - }, - "tls": { - "title": "Facoltativo — Abilita la cifratura TLS", - "intro": "Per impostazione predefinita, il listener accetta TCP/UDP non cifrato. Per cifrare il traffico syslog in transito, carica prima i tuoi file di certificato, poi riabilita il listener con il protocollo tls.", - "step1": "1 · Carica il tuo certificato e la chiave (una volta per Collector)", - "step1Note": "È possibile aggiungere un certificato CA facoltativo come terzo argomento. Omettilo per utilizzare il certificato foglia come CA.", - "step2": "2 · Riabilita il listener usando TLS" - }, - "httpsCerts": { - "title": "Carica il certificato TLS sul Collector", - "body": "Questa integrazione usa un listener HTTPS sulla porta {{port}}, quindi il Collector richiede un certificato e una chiave caricati prima di abilitarla:" - }, - "uninstall": { - "title": "Facoltativo — Disinstalla il Collector", - "body": "Esegui questo comando sull'host in cui è installato il Collector per interrompere il servizio e rimuovere tutti i suoi file." - }, - "instanceHeader": { - "title": "Intestazione di autorizzazione", - "body": "Includi questa intestazione Authorization in ogni richiesta inviata all'istanza. Il segreto della chiave API viene rivelato una sola volta al momento della sua generazione — copialo allora e incollalo al posto del segnaposto qui sotto.", - "tabSimple": "Semplice", - "tabBatch": "Batch" - }, - "manualCommand": { - "title": "Optional — Enable via the command line instead", - "intro": "Prefer the terminal? SSH into the Collector host and run the command below — it matches whatever protocol and port you have selected above.", - "certStep": "1 · Load your certificate and key (once per Collector)", - "enableStep": "2 · Enable the integration" - } - }, - "aix": { - "source": "Server AIX", - "step1": { - "title": "Abilita il listener AIX sul Collector", - "body": "Sull'host in cui è installato il Collector, esegui questo comando per aprire il listener di log AIX:", - "note": "Per usare TCP invece di UDP, sostituisci udp con tcp nel comando precedente." - }, - "step2": { - "title": "Configura AIX per l'inoltro dei log", - "body": "Sul tuo sistema AIX, configura il servizio syslog per reindirizzare i log all'host del Collector sulla porta {{port}}. Consulta la documentazione IBM per la sintassi esatta — varia tra le versioni AIX." - } - }, - "deceptivebytes": { - "source": "Deceptive Bytes", - "step1": { - "title": "Abilita il listener Deceptive Bytes sul Collector", - "body": "Sull'host in cui è installato il Collector, esegui questo comando per aprire il listener syslog Deceptive Bytes:", - "note": "Per usare TCP invece di UDP, sostituisci udp con tcp nel comando precedente." - }, - "step2": { - "title": "Configura Deceptive Bytes per l'inoltro dei log", - "body": "Nella console di gestione Deceptive Bytes, configura l'inoltro syslog per inviare gli eventi all'host del Collector sulla porta {{port}} (UDP). Deceptive Bytes emette syslog in formato CEF, che il Collector acquisisce come tipo di dato deceptive-bytes." - } - }, - "mikrotik": { - "source": "Router MikroTik", - "step1": { - "title": "Abilita il listener MikroTik sul Collector", - "body": "Sull'host in cui è installato il Collector, esegui questo comando per aprire il listener syslog MikroTik:", - "note": "Per usare TCP invece di UDP, sostituisci udp con tcp nel comando precedente." - }, - "step2": { - "title": "Configura MikroTik per l'inoltro dei log", - "body": "Sul router MikroTik, crea una logging action remota che punta all'host del Collector sulla porta {{port}} e associala agli argomenti log pertinenti. Esegui quanto segue dalla CLI RouterOS (Terminal in Winbox):", - "note": "Puoi anche configurarlo tramite Winbox: System → Logging → scheda Actions (aggiungi un'azione Remote) → poi la scheda Rules (aggiungi regole che puntano alla nuova azione)." - } - }, - "fortigate": { - "source": "Firewall FortiGate", - "step1": { - "title": "Abilita il listener FortiGate sul Collector", - "body": "Sull'host in cui è installato il Collector, esegui questo comando per aprire il listener syslog FortiGate:", - "note": "Per usare TCP invece di UDP, sostituisci udp con tcp nel comando precedente." - }, - "step2": { - "title": "Configura FortiGate per l'inoltro dei log", - "body": "Sul FortiGate, punta syslog all'host del Collector sulla porta {{port}}. Esegui quanto segue dalla CLI FortiOS (o usa Log & Report → Log Settings → Syslog nella GUI):", - "note": "Sostituisci l'indirizzo del server se il Collector è in esecuzione su un host diverso. Per più collector syslog usa syslogd2/syslogd3/syslogd4." - } - }, - "fortiweb": { - "source": "FortiWeb WAF", - "step1": { - "title": "Abilita il listener FortiWeb sul Collector", - "body": "Sull'host in cui è installato il Collector, esegui questo comando per aprire il listener syslog FortiWeb:", - "note": "Per usare TCP invece di UDP, sostituisci udp con tcp nel comando precedente." - }, - "step2": { - "title": "Configura FortiWeb per l'inoltro dei log", - "body": "Sul FortiWeb, crea una policy syslog che punta all'host del Collector sulla porta {{port}} e abilita il logging syslog. Esegui quanto segue dalla CLI FortiWeb (o usa Log & Report → Log Policy → Syslog Policy nella GUI):", - "note": "Assicurati che i tipi di log pertinenti (Attack, Event, Traffic) siano abilitati per l'invio a syslog nelle impostazioni Log & Report." - } - }, - "paloalto": { - "source": "Firewall Palo Alto", - "step1": { - "title": "Abilita il listener Palo Alto sul Collector", - "body": "Sull'host in cui è installato il Collector, esegui questo comando per aprire il listener syslog Palo Alto:", - "note": "Per usare TCP invece di UDP, sostituisci udp con tcp nel comando precedente." - }, - "step2": { - "title": "Crea un profilo server Syslog", - "body": "In PAN-OS, vai su Device → Server Profiles → Syslog e aggiungi un profilo. Imposta l'indirizzo del server su {{host}}, trasporto UDP, porta {{port}} e formato BSD." - }, - "step3": { - "title": "Invia log e applica le modifiche", - "body": "Crea un profilo Log Forwarding (Objects → Log Forwarding) che invia log di tipo Traffic, Threat e altri al profilo syslog sopra, associalo alle tue regole Security policy (Policies → Security → regola → Actions → Log Forwarding), quindi esegui Commit." - } - }, - "pfsense": { - "source": "Firewall pfSense", - "step1": { - "title": "Abilita il listener pfSense sul Collector", - "body": "Sull'host in cui è installato il Collector, esegui questo comando per aprire il listener syslog pfSense:", - "note": "Per usare TCP invece di UDP, sostituisci udp con tcp nel comando precedente." - }, - "step2": { - "title": "Abilita il logging remoto in pfSense", - "body": "Nell'interfaccia web pfSense, vai su Status → System Logs → Settings. In Remote Logging Options, spunta Enable Remote Logging, imposta un server di log remoto su {{host}}:{{port}}, scegli quali log inviare (o Everything), e clicca Save." - } - }, - "sonicwall": { - "source": "Firewall SonicWall", - "step1": { - "title": "Abilita il listener SonicWall sul Collector", - "body": "Sull'host in cui è installato il Collector, esegui questo comando per aprire il listener syslog SonicWall:", - "note": "Per usare TCP invece di UDP, sostituisci udp con tcp nel comando precedente." - }, - "step2": { - "title": "Aggiungi un server Syslog in SonicOS", - "body": "In SonicOS, vai su Device → Log → Syslog (Manage → Log → Syslog nei firmware meno recenti) e aggiungi un server Syslog con indirizzo {{host}} e porta {{port}}. Imposta il Syslog Format su ArcSight (CEF) — UTMStack analizza SonicWall in CEF — poi clicca Apply." - } - }, - "sophosxg": { - "source": "Sophos Firewall", - "step1": { - "title": "Abilita il listener Sophos Firewall sul Collector", - "body": "Sull'host in cui è installato il Collector, esegui questo comando per aprire il listener syslog Sophos Firewall:", - "note": "Per usare TCP invece di UDP, sostituisci udp con tcp nel comando precedente." - }, - "step2": { - "title": "Aggiungi un server Syslog in Sophos Firewall", - "body": "Nella console Sophos Firewall (SFOS), vai su System → System services → Log settings e aggiungi un server Syslog con indirizzo {{host}} e porta {{port}}. Scegli i tipi di log da inoltrare (firewall, IPS, ATP, web, ecc.) e clicca su Apply." - } - }, - "suricata": { - "source": "Suricata IDS", - "step1": { - "title": "Abilita il listener Suricata sul Collector", - "body": "Sull'host in cui è installato il Collector, esegui questo comando per aprire il listener Suricata:", - "note": "Per usare TCP al posto di UDP, sostituisci udp con tcp nel comando precedente." - }, - "step2": { - "title": "Invia i log Suricata EVE a syslog", - "body": "Suricata viene acquisito come JSON (EVE). Sull'host Suricata, modifica suricata.yaml e configura l'output eve-log per scrivere su syslog:", - "note": "Quindi riavvia Suricata: sudo systemctl restart suricata" - }, - "step3": { - "title": "Inoltra syslog al Collector", - "body": "Punta la facility local5 (dove Suricata scrive ora) verso il Collector. Aggiungi questa regola in /etc/rsyslog.d/60-utmstack-suricata.conf sull'host Suricata:", - "note": "Usa @@ al posto di @ per TCP. Quindi riavvia rsyslog: sudo systemctl restart rsyslog" - } - }, - "o365_graph": { - "intro": { - "title": "Come funziona", - "body": "UTMStack si connette a Microsoft 365 con un'app Azure AD registrata e interroga Microsoft Graph per gli eventi di sicurezza: allerte, incidenti, audit del directory, sign-in, rilevamenti di rischio, query di hunting e log di audit Purview. Non viene installato alcun agente nel tuo tenant.", - "diagram": { - "source": "eventi di sicurezza", - "edge": "Microsoft Graph", - "utmstackSub": "correlazione & allerte" - }, - "note": "UTMStack richiede solo accesso in sola lettura all'API Graph — non vengono richieste autorizzazioni di scrittura." - }, - "appSection": "Registrazione app Azure", - "steps": { - "azurePortal": { - "title": "Apri Microsoft Entra ID", - "body": "Apri il Portale di Azure (portal.azure.com) e clicca su Microsoft Entra ID." - }, - "appRegistrations": { - "title": "Vai a Registrazioni app", - "body": "Nel menu a sinistra, clicca su Registrazioni app." - }, - "registerApp": { - "title": "Registra una nuova app", - "body": "Clicca su Nuova registrazione. Nominala UTMStack Graph Dev, seleziona Solo account in questo directory organizzativo (Single-tenant) e clicca su Registra." - }, - "clientSecret": { - "title": "Crea un segreto client", - "body": "Vai su Certificati e segreti → Nuovo segreto client. Aggiungi una descrizione, imposta la scadenza su 730 giorni (24 mesi) e clicca su Aggiungi.", - "copyNote": "Copia subito il valore del segreto — viene mostrato solo una volta e non potrà essere recuperato in seguito." - }, - "apiPermissions": { - "title": "Aggiungi le autorizzazioni Microsoft Graph", - "body": "Vai su Autorizzazioni API → Aggiungi un'autorizzazione e seleziona Microsoft Graph, poi scegli Autorizzazioni dell'applicazione." - }, - "graphPermissions": { - "title": "Aggiungi le quattro autorizzazioni Graph", - "body": "Aggiungi SecurityEvents.Read.All, Directory.Read.All, AuditLog.Read.All e IdentityRiskEvent.Read.All." - }, - "adminConsent": { - "title": "Concedi il consenso amministratore", - "body": "Tornato in Autorizzazioni API, clicca su Concedi consenso amministratore per {tenant} e conferma." - }, - "noteIds": { - "title": "Copia gli ID dell'app", - "body": "Vai alla Panoramica dell'app e copia l'ID applicazione (client) e l'ID directory (tenant). Ti serve anche il valore del segreto copiato al passaggio 4." - } - }, - "credentialsSection": "Credenziali", - "credentials": { - "title": "Connetti il tuo tenant Microsoft 365", - "body": "Inserisci i dettagli dai passaggi sopra. UTMStack verifica le credenziali prima di salvarle. Puoi aggiungere più gruppi di configurazione." - }, - "fields": { - "tenantId": { - "label": "ID Tenant (ID Directory)" - }, - "clientId": { - "label": "ID Client (ID Applicazione)" - }, - "clientSecret": { - "label": "Segreto Client" - }, - "cloudEnv": { - "label": "Ambiente cloud (facoltativo)", - "hint": "Commercial (default), GCC, GCCHigh o DoD" + "action": { + "INCIDENT_CREATED": "Incidente creato", + "INCIDENT_ALERT_ADD": "Avvisi aggiunti", + "INCIDENT_ALERT_STATUS_CHANGED": "Stato degli avvisi cambiato", + "INCIDENT_STATUS_CHANGE": "Stato cambiato", + "INCIDENT_NOTE_ADD": "Nota aggiunta", + "INCIDENT_NOTE_CHANGE": "Nota modificata", + "INCIDENT_ASSIGNED": "Assegnazione cambiata" + }, + "create": { + "title": "Crea incidente", + "stepIndicator": "Passaggio {{current}} di {{total}}", + "selectedCount": "{{count}} avvisi selezionati", + "submit": "Crea", + "success": "Incidente creato", + "error": "Impossibile creare l'incidente", + "details": { + "nameLabel": "Nome", + "namePlaceholder": "Titolo breve e descrittivo", + "descriptionLabel": "Descrizione", + "descriptionPlaceholder": "Contesto, ambito, note iniziali…" } - } } - }, - "cloud": { - "howItWorksTitle": "Come funziona", - "howItWorksBody": "{{name}} viene eseguito completamente all'interno di UTMStack — nessun agente o collector da distribuire. Fornisci credenziali API di sola lettura e UTMStack estrarrà gli eventi in base a una pianificazione, li analizzerà e li ingerirà in Log Explorer.", - "connectionTitle": "Connessione", - "noFields": "Nessun campo di connessione configurato.", - "testConnection": "Prova connessione", - "save": "Salva", - "afterTitle": "Cosa vedrai dopo la connessione", - "after1": "UTMStack esegue un recupero iniziale degli eventi recenti.", - "after2": "Da allora in poi, gli eventi vengono estratti ogni 1–5 minuti (dipende dall'API).", - "after3": "L'integrazione appare sotto Origini dati con lo stato di estrazione attuale e il ritardo.", - "tenants": { - "title": "Gruppi di configurazione configurati", - "empty": "Nessun gruppo di configurazione. Aggiungi il primo qui sotto.", - "loading": "Caricamento gruppi di configurazione…", - "nameLabel": "Nome del gruppo di configurazione", - "namePlaceholder": "es. acme-prod", - "add": "Aggiungi gruppo di configurazione", - "update": "Aggiorna gruppo di configurazione", - "delete": "Elimina", - "edit": "Modifica", - "cancel": "Annulla", - "editing": "Modifica: {{name}}", - "selectFile": "Seleziona file", - "replaceFile": "Sostituisci file", - "fileLoaded": "File caricato", - "invalidJson": "Impossibile interpretare il file come JSON.", - "createError": "Impossibile creare il gruppo di configurazione. Riprova.", - "updateError": "Impossibile aggiornare il gruppo di configurazione. Riprova.", - "createSuccess": "Gruppo di configurazione creato con successo.", - "updateSuccess": "Gruppo di configurazione aggiornato con successo." - }, - "google": { - "sections": { - "createTopic": { - "title": "1 · Crea un argomento Pub/Sub", - "body": "Nella console di Google Cloud, apri Pub/Sub → Argomenti e crea un nuovo argomento. UTMStack riceverà gli eventi tramite questo argomento.", - "docLabel": "Apri la pagina dei topic Pub/Sub" - }, - "createSubscription": { - "title": "2 · Crea una sottoscrizione", - "body": "All'interno dell'argomento, crea una sottoscrizione di tipo Pull. UTMStack preleva i messaggi da questa sottoscrizione." - }, - "configureSubscription": { - "title": "3 · Configura la sottoscrizione", - "body": "Imposta la durata di conservazione dei messaggi su un valore adatto alla tua tolleranza di disservizio (7 giorni di default va bene). Lascia la scadenza di conferma a 10 secondi e l'expiration su «Mai»." - }, - "logsRouter": { - "title": "4 · Apri il Logs Router", - "body": "Vai in Logging → Logs Router e crea un nuovo sink. È quello che inoltra i log del progetto all'argomento Pub/Sub creato sopra." - }, - "sinkDestination": { - "title": "5 · Punta il sink all'argomento", - "body": "Scegli Argomento Cloud Pub/Sub come destinazione del sink e seleziona l'argomento creato. Usa i filtri di inclusione/esclusione per limitare cosa viene inoltrato." - }, - "serviceAccount": { - "title": "6 · Crea un service account", - "body": "Apri IAM e amministrazione → Service account e crea un nuovo service account. Assegnagli il ruolo Editor Pub/Sub in modo che UTMStack possa leggere dalla sottoscrizione.", - "docLabel": "Apri la pagina degli account di servizio" - }, - "serviceAccountKey": { - "title": "7 · Genera una chiave per il service account", - "body": "Apri il service account, vai alla scheda Chiavi e aggiungi una nuova chiave. Scegli JSON come tipo di chiave." - }, - "downloadKey": { - "title": "8 · Scarica e carica la chiave JSON", - "body": "Salva il file JSON scaricato da Google: il contenuto va nel campo «Chiave JSON del service account» qui sotto." - } - }, - "fields": { - "projectId": { - "label": "ID progetto" - }, - "subscription": { - "label": "Nome sottoscrizione" - }, - "jsonKey": { - "label": "Chiave JSON del service account" - } - }, - "intro": { - "title": "Come funziona", - "body": "UTMStack legge l'attività di audit direttamente da Google Cloud tramite Pub/Sub. Un sink del Logs Router instrada i log del progetto in un topic Pub/Sub; UTMStack esegue un puller interno che legge una Pull subscription su quel topic utilizzando la chiave dell'account di servizio. Non viene installato nulla nel progetto GCP.", - "diagram": { - "source": "Cloud Logging", - "edge1": "Logs Router", - "pubsub": "Pub/Sub", - "pubsubSub": "topic + subscription", - "edge2": "preleva", - "utmstackSub": "alert e correlazione" - }, - "note": "Nessun agente viene eseguito in GCP — UTMStack preleva i messaggi dalla sottoscrizione Pub/Sub utilizzando la chiave JSON dell'account di servizio fornita di seguito." - }, - "credentials": { - "title": "Configurazione Pub/Sub", - "body": "Usa i valori raccolti in precedenza per configurare UTMStack. Puoi monitorare più di un progetto salvando configurazioni aggiuntive.", - "mapping": { - "intro": "Riferimento campi", - "projectId": "Project ID — il progetto GCP che contiene il topic, la sottoscrizione e il sink", - "subscription": "Nome della sottoscrizione — la Pull subscription creata al passaggio 2", - "jsonKey": "Chiave JSON dell'account di servizio — il file scaricato al passaggio 8" - } - } + }, + "alertingRules": { + "title": "Regole di allerta", + "subtitle": "Regole di correlazione che trasformano gli eventi in allarmi. Attiva, regola o crea le tue.", + "new": "Nuova regola", + "refresh": "Aggiorna", + "empty": "Nessuna regola corrispondente.", + "loadError": "Impossibile caricare le regole.", + "retry": "Riprova", + "deleteConfirm": "Eliminare la regola “{{name}}”?", + "adversary": { + "origin": "Origine", + "target": "Destinazione" }, - "azure": { - "sections": { - "sharedAccessPolicy": { - "title": "2 · Aggiungi un criterio di accesso condiviso", - "body": "Apri l'Event Hub → Criteri di accesso condiviso e crea un nuovo criterio con solo il permesso Listen." - }, - "connectionString": { - "title": "3 · Copia la stringa di connessione primaria", - "body": "Apri il criterio e copia la stringa di connessione primaria. È simile a: Endpoint=sb://...;SharedAccessKeyName=...;SharedAccessKey=..." - }, - "consumerGroup": { - "title": "4 · Crea un consumer group dedicato", - "body": "Apri l'Event Hub → Consumer group e creane uno nuovo per UTMStack. Non riutilizzare $Default: dai a UTMStack un proprio gruppo per evitare conflitti di checkpoint con altri consumer.", - "warn": "Crea un consumer group specificamente per UTMStack. Non utilizzare $Default o altri gruppi già in uso — riutilizzare un consumer group tra consumer non correlati può causare comportamenti imprevisti ed eventi persi. Tutte le istanze UTMStack devono condividere lo stesso consumer group per elaborare gli eventi insieme." - }, - "storageContainer": { - "title": "6 · Crea un container nell'account di archiviazione", - "body": "Nell'account di archiviazione → Container, crea un nuovo container. Annota il nome del container e la stringa di connessione dell'account (Chiavi di accesso → Stringa di connessione)." - }, - "eventGrid": { - "title": "7 · Registra il provider di risorse Event Grid", - "body": "In Sottoscrizioni → Provider di risorse, registra Microsoft.EventGrid se non lo è già. Permette ad Azure di inoltrare eventi a livello di sottoscrizione al tuo Event Hub." - }, - "createEventHub": { - "title": "Crea un Event Hub", - "body": "Nel portale Azure, crea un namespace Event Hubs e un Event Hub al suo interno. UTMStack leggerà gli eventi da questo hub.", - "docLabel": "Avvio rapido: Creare un event hub tramite il portale Azure" - }, - "createStorageAccount": { - "title": "Crea un Storage Account", - "body": "UTMStack ha bisogno di un Storage Account per salvare i checkpoint della posizione di lettura. Creane uno nella stessa area geografica dell'Event Hub.", - "docLabel": "Avvio rapido: Creare un account di archiviazione" - }, - "storageConnection": { - "title": "Copia la stringa di connessione del Storage Account", - "body": "Ottieni la stringa di connessione del Storage Account con chiave in: All services → Storage accounts → il tuo account → Access keys. UTMStack la usa per archiviare i checkpoint dell'Event Hub." - }, - "createEventSubscription": { - "title": "Crea una sottoscrizione eventi", - "body": "Nel pannello Events della sottoscrizione, crea un nuovo evento cliccando su Events → Event Subscription." - }, - "configureEventSubscription": { - "title": "Punta la sottoscrizione eventi verso il tuo Event Hub", - "body": "Configura la sottoscrizione eventi per inviare i log all'Event Hub creato al passaggio 1." - } - }, - "fields": { - "eventHubConnection": { - "label": "Stringa di connessione Event Hub" - }, - "consumerGroup": { - "label": "Consumer group" - }, - "storageContainer": { - "label": "Nome del container di archiviazione" - }, - "storageConnection": { - "label": "Stringa di connessione dell'account di archiviazione" - } - }, - "intro": { - "title": "Come funziona", - "body": "UTMStack legge l'attività di audit direttamente da un Azure Event Hub. Configuri la sottoscrizione Azure per trasmettere gli eventi in un Event Hub; UTMStack esegue un puller interno che legge quell'hub e salva i checkpoint in un Storage Account. Non viene installato nulla nel tenant Azure.", - "diagram": { - "source": "eventi della sottoscrizione", - "edge1": "instrada verso", - "eventHub": "Event Hub", - "eventHubSub": "flusso di eventi", - "edge2": "preleva", - "utmstackSub": "alert e correlazione" - }, - "note": "Nessun agente viene eseguito in Azure — UTMStack preleva gli eventi dall'Event Hub utilizzando le stringhe di connessione fornite di seguito." - }, - "sampleLabel": "Esempio di stringa di connessione:", - "credentials": { - "title": "Configurazione Event Hub", - "body": "Usa i dati raccolti nei passaggi precedenti per configurare UTMStack. Puoi aggiungere più di un Event Hub salvando configurazioni aggiuntive.", - "mapping": { - "intro": "Riferimento campi", - "eventHubConnection": "Stringa di connessione Event Hub — valore ottenuto al passaggio 3", - "consumerGroup": "Consumer group — valore ottenuto al passaggio 4", - "storageContainer": "Nome del container di archiviazione — valore ottenuto al passaggio 6", - "storageConnection": "Stringa di connessione dell'account di archiviazione — valore ottenuto al passaggio 7" - } - } + "state": { + "active": "Attiva", + "inactive": "Inattiva" }, - "aws": { - "fields": { - "accessKeyId": { - "label": "ID chiave di accesso AWS" - }, - "secretAccessKey": { - "label": "Chiave di accesso segreta AWS" - }, - "region": { - "label": "Regione AWS predefinita" - }, - "logGroupName": { - "label": "Nome del log group" - } - }, - "intro": { - "title": "Come funziona", - "body": "UTMStack legge l'attività di audit direttamente da AWS CloudWatch Logs. CloudTrail acquisisce le chiamate API e gli eventi di gestione dell'account AWS, li invia a un gruppo di log CloudWatch e UTMStack interroga quel gruppo per acquisire e correlare gli eventi.", - "diagram": { - "source": "eventi API", - "edge1": "CloudTrail", - "cloudwatchSub": "gruppi di log", - "edge2": "interroga", - "utmstackSub": "alert e correlazione" - }, - "note": "Nessun agente viene installato su AWS — UTMStack preleva gli eventi di log utilizzando le credenziali IAM in sola lettura fornite di seguito." - }, - "iamSection": "Configura utente IAM", - "iam": { - "dashboard": { - "title": "Apri il dashboard IAM", - "body": "Apri la console AWS, vai al dashboard IAM e seleziona Users." - }, - "addUser": { - "title": "Aggiungi un utente", - "body": "Clicca su Add user, inserisci un nome utente descrittivo e procedi al passaggio successivo." - }, - "attachPolicy": { - "title": "Associa la policy in sola lettura", - "body": "In Permissions, associa la policy richiesta. Seleziona CloudWatchLogsReadOnlyAccess per l'accesso in sola lettura a CloudWatch." - }, - "createUser": { - "title": "Crea l'utente", - "body": "Rivedi la configurazione e clicca su Create user per eseguire il provisioning dell'account." - }, - "openUser": { - "title": "Apri il nuovo utente", - "body": "Apri l'utente appena creato cliccando sul suo nome per visualizzare i dettagli e gestire le credenziali." - }, - "securityTab": { - "title": "Vai a Security credentials", - "body": "Seleziona la scheda Security credentials per creare chiavi di accesso programmatico." - }, - "createKey": { - "title": "Crea una chiave di accesso", - "body": "Clicca su Create access key e scegli l'opzione per un'applicazione in esecuzione al di fuori di AWS (accesso programmatico)." - }, - "confirmKey": { - "title": "Conferma la creazione", - "body": "Conferma la creazione della chiave di accesso. AWS genererà un Access Key ID e una Secret Access Key." - }, - "downloadKey": { - "title": "Salva le credenziali", - "body": "Scarica il file delle credenziali o copia l'Access Key ID e la Secret Access Key in un luogo sicuro — la Secret Access Key viene mostrata una sola volta." - } - }, - "credentials": { - "title": "Inserisci le credenziali", - "body": "Incolla l'Access Key ID e la Secret Access Key ottenuti nei passaggi precedenti. UTMStack verifica le credenziali con AWS prima di salvarle." - }, - "cloudwatchSection": "Configura AWS CloudWatch", - "cloudwatch": { - "createGroup": { - "title": "Crea un gruppo di log CloudWatch", - "body": "Apri la console CloudWatch, scegli Log management e clicca su Create log group." - }, - "nameGroup": { - "title": "Assegna un nome al gruppo di log e imposta la conservazione", - "body": "Inserisci il nome del gruppo di log utmstack e imposta la conservazione a 1 giorno. Clicca su Create log group." - }, - "openTrail": { - "title": "Apri CloudTrail e crea un trail", - "body": "Nella console CloudTrail, clicca su Create trail per iniziare a configurare un nuovo trail." - }, - "configureTrail": { - "title": "Configura la distribuzione, la validazione e l'integrazione con CloudWatch", - "body": "Nel modulo di creazione CloudTrail, imposta le seguenti opzioni:", - "items": [ - "Nome e ambito del trail: inserisci un nome descrittivo; abilita Apply trail to all accounts in my organization se hai bisogno di una raccolta a livello di organizzazione.", - "Destinazione S3: scegli Create new S3 bucket (o seleziona un bucket esistente) per la distribuzione dei log non elaborati.", - "Crittografia: abilita Log file SSE-KMS e seleziona la chiave KMS appropriata.", - "Validazione file di log: abilita per garantire l'integrità dei log distribuiti (consigliato).", - "CloudWatch Logs: abilita la distribuzione a CloudWatch, seleziona Use existing log group e inserisci il nome esatto utmstack.", - "Ruolo IAM: fornisci o crea il ruolo che CloudTrail assumerà per scrivere su S3 e pubblicare su CloudWatch." - ] - }, - "eventTypes": { - "title": "Seleziona i tipi di evento", - "body": "Abilita le categorie di eventi necessarie per il monitoraggio e la verifica.", - "management": { - "label": "1 · Management events", - "body": "Abilita Management events e seleziona All per registrare tutta l'attività API che gestisce le risorse AWS (creazione, aggiornamento, eliminazione)." - }, - "data": { - "label": "2 · Data events", - "body": "Aggiungi un Data event. Scegli S3 e seleziona Log all events per acquisire operazioni a livello di oggetto come GetObject e PutObject." - }, - "network": { - "label": "3 · Network activity events", - "body": "Nella sezione Network Activities aggiungi almeno un servizio (es. ec2.amazonaws.com) e abilita Log all events." - } - }, - "review": { - "title": "Rivedi e crea il trail", - "body": "Nella schermata Configure event aggregation accetta i valori predefiniti (o modificali se necessario). Rivedi tutte le impostazioni e clicca su Create trail." - } - } - }, - "crowdstrike": { - "intro": { - "title": "Come funziona", - "body": "UTMStack legge rilevamenti e attività di audit direttamente dall'API CrowdStrike Falcon Event Streams. Crei un client API in Falcon con scope Event Streams; UTMStack esegue un puller interno che trasmette in streaming gli eventi usando tali credenziali. Non viene installato nulla sugli endpoint né in Falcon.", - "diagram": { - "source": "rilevamenti ed eventi", - "edge1": "Event Streams API", - "api": "Falcon API", - "apiSub": "event stream", - "edge2": "recupera", - "utmstackSub": "alert e correlazione" - }, - "note": "UTMStack non distribuisce alcun agente — recupera gli eventi da Falcon utilizzando le credenziali del client API in sola lettura fornite di seguito." - }, - "sections": { - "apiClients": { - "title": "Apri API Clients and Keys", - "body": "Nella console Falcon, apri il menu (icona hamburger, in alto a sinistra) e vai su Support and resources → API Clients and Keys." - }, - "createClient": { - "title": "Crea un nuovo client API", - "body": "Clicca su Create API Client per avviare la definizione di un nuovo client." - }, - "scopes": { - "title": "Assegna un nome al client e concedi lo scope Event Streams", - "body": "Assegna al client un nome descrittivo (UTMStack lo usa per identificare la sorgente degli eventi) e seleziona gli scope API richiesti per Event Streams. Clicca su Create per generare le credenziali." - }, - "recordCredentials": { - "title": "Registra le credenziali", - "body": "Copia il Client ID, il Client Secret e il Base URL per la tua regione CrowdStrike. Il segreto viene mostrato una sola volta — conservalo in modo sicuro. Incollerai tutti e tre nel modulo seguente." - } - }, - "credentials": { - "title": "Configurazione del client API", - "body": "Usa le credenziali dei passaggi precedenti per configurare UTMStack. Puoi aggiungere più di un client CrowdStrike salvando configurazioni aggiuntive.", - "mapping": { - "intro": "Riferimento ai campi", - "appName": "App name — nome descrittivo del client dal passaggio 3 (identifica la sorgente degli eventi)", - "clientId": "Client ID — valore registrato al passaggio 4", - "clientSecret": "Client Secret — valore registrato al passaggio 4 (mostrato una sola volta)", - "cloudRegionUrl": "Base URL — endpoint della tua regione, es. https://api.crowdstrike.com (us-1), https://api.us-2.crowdstrike.com (us-2), https://api.eu-1.crowdstrike.com (eu-1)" - } - }, - "fields": { - "appName": { - "label": "App name" - }, - "clientId": { - "label": "Client ID" - }, - "clientSecret": { - "label": "Client Secret" - }, - "cloudRegionUrl": { - "label": "Base URL (regione cloud)" - } - } - } - }, - "custom": { - "whenTitle": "Quando usarlo", - "whenBody": "Quando la tua origine non è nel catalogo. Inoltri syslog o JSON arbitrario a UTMStack e definisci un parser per normalizzare i campi.", - "endpointsTitle": "Endpoint", - "syslogUdp": "Syslog (UDP)", - "syslogTls": "Syslog (TLS)", - "httpJson": "HTTP / JSON", - "payloadTitle": "Esempio di payload JSON", - "parserTitle": "Definisci il parser", - "parserBody": "Gli eventi in ingresso vengono memorizzati sotto il tipo di dato {{dataType}}. Aggiungi un filtro di parsing affinché il payload grezzo venga mappato in campi strutturati, quindi crea regole di avviso.", - "openEditor": "Apri editor parser", - "powershellLabel": "PowerShell (Esegui come amministratore)", - "linuxLabel": "Linux — bash", - "macosLabel": "macOS — bash", - "exampleLabel": "Esempio di destinazione syslog su {{name}}:", - "intro": { - "title": "Come funziona", - "body": "Un'integrazione personalizzata acquisisce i log da qualsiasi sorgente non coperta dai moduli integrati. Installa il UTMStack Collector, registra un listener per i tuoi dati con il protocollo scelto e punta la sorgente verso di esso.", - "note": "Scegli di seguito il protocollo che la tua sorgente può inviare (syslog UDP/TCP/TLS, oppure HTTP/HTTPS per JSON) — il Collector crea automaticamente il tipo di dato." - }, - "diagram": { - "source": "La tua sorgente", - "sourceSub": "qualsiasi app o dispositivo", - "forwarder": "Collector", - "ingests": "acquisisce", - "utmstackSub": "alert e correlazione" - }, - "choose": { - "title": "Scegli protocollo e porta", - "body": "Seleziona come la tua sorgente invia i dati e la porta su cui il Collector deve mettersi in ascolto, quindi esegui il comando di attivazione sull'host del Collector.", - "portLabel": "Porta del listener", - "tlsFirst": "Prima carica il certificato TLS e la chiave sul Collector:", - "enableLabel": "Poi abilita l'integrazione:", - "authNote": "Per richiedere l'autenticazione, aggiungi --auth bearer (token) o --auth hmac — il Collector stampa un token da usare nell'header Authorization." - }, - "send": { - "title": "Punta la sorgente verso il Collector", - "bodyNetwork": "Configura la tua sorgente per inviare syslog {{proto}} a {{host}}:{{port}}. La maggior parte dei dispositivi dispone di un'impostazione remote-syslog o di inoltro log remoto per questo.", - "bodyHttp": "Invia i tuoi eventi come JSON via HTTP POST a {{endpoint}}. Il corpo di ogni richiesta è un evento JSON:", - "httpBindNote": "Il listener HTTP/HTTPS si collega a 127.0.0.1 (l'host del Collector) per impostazione predefinita, quindi invia dall'app in esecuzione su quell'host — oppure usalo con un reverse proxy. Per sorgenti remote, usa syslog (UDP/TCP/TLS)." - }, - "manualCommand": { - "title": "Optional — Enable via the command line instead", - "intro": "Prefer the terminal? SSH into the Collector host and run the command below — it matches whatever protocol and port you have selected above." + "owner": { + "system": "Sistema", + "custom": "Personalizzata" + }, + "toolbar": { + "search": "Cerca regole…", + "allCategories": "Tutte le categorie", + "allAdversaries": "Tutti gli avversari", + "allStates": "Tutti gli stati", + "allOwners": "Tutte le origini", + "allDataTypes": "Tutti i tipi" + }, + "table": { + "name": "Regola", + "category": "Categoria", + "technique": "Tecnica", + "adversary": "Avversario", + "impact": "Impatto", + "active": "Attiva", + "dataTypes": "Tipi di dato", + "selectAll": "Seleziona tutto", + "selectRow": "Seleziona {{name}}" + }, + "export": { + "all": "Esporta tutto", + "selected": "Esporta ({{count}})", + "error": "Impossibile esportare le regole" + }, + "view": { + "description": "Descrizione", + "details": "Dettagli", + "impact": "Impatto (C·I·D)", + "dataTypes": "Tipi di dato", + "updated": "Aggiornata", + "relPath": "Percorso", + "definition": "Condizione (CEL)", + "correlationSteps": "Passi di correlazione", + "correlation": "Correlazione", + "groupBy": "Raggruppa per", + "deduplicateBy": "Deduplica per", + "references": "Riferimenti" + }, + "editor": { + "createTitle": "Nuova regola", + "edit": "Modifica", + "delete": "Elimina", + "export": "Esporta", + "cancel": "Annulla", + "save": "Salva", + "metadata": "Metadati", + "name": "Nome", + "confidentiality": "Riservatezza", + "integrity": "Integrità", + "availability": "Disponibilità", + "dataTypes": "Tipi di dato", + "dataTypesHint": "separati da virgola", + "activeOnSave": "Attiva", + "definitionSection": "Definizione", + "where": "Condizione (CEL)", + "whereHint": "Espressione CEL valutata per evento", + "correlationSteps": "Passi di correlazione", + "correlationStepsHint": "array JSON", + "jsonArray": "array JSON", + "nameRequired": "Il nome è obbligatorio", + "definitionRequired": "La condizione è obbligatoria", + "invalidJson": "Un campo della definizione ha JSON non valido", + "addStep": "Aggiungi passo di correlazione", + "step": "Passo {{n}}", + "removeStep": "Rimuovi passo", + "indexPattern": "Pattern indice", + "within": "Finestra", + "count": "Conteggio", + "conditions": "Condizioni", + "field": "Campo", + "value": "Valore", + "addCondition": "Aggiungi condizione", + "orGroup": "Gruppo Or {{n}}", + "addOr": "Aggiungi gruppo Or", + "removeOr": "Rimuovi", + "fieldsHint": "nomi dei campi", + "referencesHint": "URL", + "visual": "Visuale", + "code": "Codice", + "dataTypesPick": "Seleziona…", + "dataTypesSearch": "Cerca tipi di dato…", + "dataTypesNone": "Nessun tipo di dato", + "visualTab": "Visuale", + "codeTab": "Codice", + "yamlError": "Impossibile applicare lo YAML: {{error}}", + "test": "Test" + }, + "toast": { + "activated": "Regola attivata", + "deactivated": "Regola disattivata", + "toggleError": "Impossibile cambiare lo stato della regola", + "deleted": "Regola eliminata", + "deleteError": "Impossibile eliminare la regola", + "created": "Regola creata", + "saved": "Regola salvata", + "saveError": "Impossibile salvare la regola" + }, + "operator": { + "filter_term": "uguale (term)", + "must_not_term": "diverso (term)", + "filter_match": "corrisponde (testo)", + "must_not_match": "non corrisponde (testo)" + }, + "where": { + "matchPrefix": "Soddisfa", + "all": "tutte", + "any": "almeno una", + "matchSuffix": "di queste condizioni:", + "negate": "Nega", + "listHint": "separati da virgole", + "advanced": "Questa condizione usa CEL avanzato — modificala in Codice o ricostruiscila visivamente.", + "and": "E", + "or": "O" + }, + "celOp": { + "exists": "esiste", + "equals": "uguale a", + "equalsIgnoreCase": "uguale (senza maiusc.)", + "contains": "contiene", + "oneOf": "è uno di", + "containsAll": "contiene tutti", + "startsWith": "inizia con", + "endsWith": "finisce con", + "regexMatch": "regex", + "lessThan": "<", + "lessOrEqual": "≤", + "greaterThan": ">", + "greaterOrEqual": "≥", + "inCIDR": "in CIDR", + "isHour": "l’ora è", + "isMinute": "il minuto è", + "isDayOfWeek": "il giorno è", + "isWeekend": "è weekend", + "isWorkDay": "è giorno feriale", + "isBetweenTime": "ora tra" + }, + "import": { + "button": "Importa", + "error": "Importazione non riuscita", + "resultTitle": "Risultati dell'importazione", + "approved": "Approvate", + "rejected": "Rifiutate", + "done": "Fatto" + }, + "test": "Test" + }, + "regexPatterns": { + "title": "Espressioni regolari", + "subtitle": "Espressioni regolari riutilizzabili referenziate dai filtri di parsing.", + "new": "Nuovo pattern", + "search": "Cerca pattern…", + "refresh": "Aggiorna", + "view": "Visualizza", + "system": "Sistema", + "user": "Personalizzato", + "loading": "Caricamento pattern…", + "loadError": "Impossibile caricare i pattern.", + "retry": "Riprova", + "empty": "Nessun pattern corrisponde a questa vista.", + "tabs": { + "all": "Tutti", + "system": "Sistema", + "user": "Personalizzati" + }, + "cols": { + "pattern": "Pattern", + "definition": "Definizione", + "type": "Tipo" + }, + "editor": { + "titleNew": "Nuovo pattern", + "patternId": "ID pattern", + "patternIdHint": "Nome univoco referenziato dai filtri.", + "description": "Descrizione", + "descriptionPlaceholder": "Cosa riconosce questo pattern (opzionale)", + "definition": "Definizione (regex)", + "definitionHint": "Un'espressione regolare. Può referenziare altri pattern.", + "readOnly": "Pattern di sistema — sola lettura.", + "save": "Salva", + "saving": "Salvataggio…", + "delete": "Elimina", + "confirmDelete": "Conferma eliminazione", + "cancel": "Annulla" + }, + "toast": { + "saved": "Pattern salvato", + "saveError": "Salvataggio del pattern non riuscito", + "deleted": "Pattern eliminato", + "deleteError": "Eliminazione del pattern non riuscita", + "patternIdRequired": "L'ID pattern è obbligatorio", + "definitionRequired": "La definizione è obbligatoria" } - }, - "remoteEnable": { - "title": "Abilita questa integrazione da remoto", - "body": "Scegli un Collector, scegli il protocollo e la porta, quindi abilita l'integrazione — non è necessario SSH.", - "noPermission": "Non hai il permesso di gestire le integrazioni remote. Chiedi a un amministratore di concedere il permesso integrations.write.", - "loadingCollectors": "Caricamento Collectors…", - "noCollectors": "Nessun Collector è ancora registrato. Installane uno sopra per abilitare le integrazioni da remoto.", - "forwarderOffline": "Questo Collector è offline e non può ricevere modifiche di configurazione in questo momento.", - "legendOnline": "{{count}} online", - "legendOffline": "{{count}} offline", - "legendTotal": "{{count}} totali", - "forwarderLabel": "Collector", - "protoLabel": "Protocollo", - "portLabel": "Porta", - "currentStateLoading": "Verifica della configurazione attuale…", - "currentlyEnabled": "Attualmente: abilitato · {{proto}} · porta {{port}}", - "currentlyDisabled": "Attualmente: disabilitato · {{proto}} · porta {{port}}", - "authLabel": "Autenticazione", - "authNone": "Nessuna", - "authBearer": "Bearer token", - "authHmac": "Firma HMAC", - "pathLabel": "Percorso", - "signatureHeaderLabel": "Header di firma", - "certTitle": "Certificato TLS", - "certLoading": "Verifica dello stato del certificato…", - "certLoaded": "Un certificato valido è già caricato su questo Collector.", - "certMissing": "Nessun certificato caricato ancora — caricane uno per abilitare questo protocollo.", - "certInvalid": "Il certificato caricato non è valido: {{error}}", - "certPemLabel": "Certificato", - "keyPemLabel": "Chiave privata", - "caPemLabel": "Certificato CA", - "uploadCertsButton": "Carica certificato", - "certUploadSuccess": "Certificato caricato.", - "certUploadError": "Caricamento del certificato non riuscito.", - "certReadError": "Non è stato possibile leggere il file o i file selezionati.", - "enableButton": "Abilita integrazione", - "disableButton": "Disabilita integrazione", - "enableSuccess": "Integrazione abilitata.", - "disableSuccess": "Integrazione disabilitata.", - "enableError": "Aggiornamento dell'integrazione non riuscito.", - "secretWarning": "Archivia questo token in modo sicuro — non verrà visualizzato di nuovo.", - "sendToInstance": "Invia all'istanza", - "enterpriseFeature": "Questa è una funzionalità Enterprise.", - "addCollector": "Aggiungi Collector", - "addApiKey": "Aggiungi chiave API", - "apiKeyLabel": "Chiave API", - "apiKeyHint": "Prima ti servirà una chiave API.", - "apiKeyPlaceholder": "Seleziona una chiave API", - "apiKeyAddNew": "Aggiungi chiave API…", - "apiKeyNone": "Nessuna chiave API ancora", - "forwarderNoRemoteControl": "Questo forwarder è stato installato con il controllo remoto disattivato. Ignora la configurazione inviata da qui, e questo si può cambiare solo sulla macchina stessa." - } - }, - "codeBlock": { - "copy": "Copia", - "copied": "Copiato" - }, - "createDrawer": { - "title": "Nuova integrazione personalizzata", - "moduleName": "Nome modulo", - "moduleNameHint": "Identificatore univoco. Senza spazi.", - "moduleNamePlaceholder": "la-mia-app-personalizzata", - "prettyName": "Nome visualizzato", - "prettyNamePlaceholder": "La Mia App Personalizzata", - "dataType": "Tipo di dati", - "dataTypePlaceholder": "Identificatore univoco per questo tipo di dati", - "icon": "Icona", - "iconHint": "PNG, SVG, JPEG, GIF o WEBP. Max 3MB. Usato come logo dell'integrazione.", - "iconPreview": "Anteprima icona", - "dataTypeExists": "Questo tipo di dati esiste già", - "invalidFileType": "L'icona deve essere un file immagine valido (PNG, JPEG, SVG, GIF, WEBP)", - "fileTooLarge": "L'icona non deve superare 3MB", - "fileReadError": "Errore nella lettura del file", - "cancel": "Annulla", - "create": "Crea integrazione", - "creating": "Creazione…", - "editTitle": "Modifica integrazione", - "save": "Salva", - "saving": "Salvataggio…", - "currentIcon": "Icona corrente — carica un file per sostituirla", - "name": "Nome dell'integrazione", - "namePlaceholder": "es. Acme Firewall", - "description": "Descrizione", - "descriptionPlaceholder": "Cosa acquisisce questa integrazione e perché (facoltativo)", - "identifierHint": "Salvato come “{{id}}” (derivato dal nome)", - "nameTaken": "Questo nome di integrazione non può essere utilizzato — esiste già un'integrazione con quell'identificatore.", - "removeIcon": "Rimuovi icona", - "defaultIconNote": "Icona predefinita — carica un file per usare la tua." - }, - "toast": { - "created": "Integrazione creata", - "updated": "Integrazione aggiornata", - "updateError": "Aggiornamento dell'integrazione non riuscito" - }, - "delete": { - "title": "Elimina integrazione", - "confirm": "Eliminare questa integrazione?", - "yes": "Elimina", - "no": "Annulla", - "deleted": "Integrazione eliminata", - "error": "Eliminazione dell'integrazione non riuscita" - }, - "modules": { - "WINDOWS_AGENT": "Raccogli l'attività di sistema Windows, sicurezza e log degli eventi tramite l'agente leggero UTMStack installato su ciascun host.", - "LINUX_AGENT": "Raccogli i log di sistema Linux, autenticazione e audit tramite l'agente leggero UTMStack installato su ciascun host.", - "MACOS": "Raccogli l'attività di log di sistema e sicurezza di macOS dagli endpoint Apple Mac tramite l'agente leggero UTMStack.", - "VMWARE": "Acquisisci il syslog dell'hypervisor VMware ESXi in modo che l'attività e gli eventi dell'host di virtualizzazione vengano monitorati in UTMStack.", - "NETFLOW": "Acquisisci i record NetFlow da router e switch per monitorare i pattern di traffico di rete e rilevare anomalie del traffico.", - "AWS_IAM_USER": "Acquisisci l'attività dell'account AWS e le chiamate API tramite CloudTrail e CloudWatch per controllare l'utilizzo cloud, gli accessi e le modifiche.", - "AZURE": "Acquisisci i log di piattaforma e attività di Microsoft Azure per monitorare i workload cloud, l'identità e le modifiche alle risorse.", - "O365": "Acquisisci i log di audit di Microsoft 365 su Exchange, Teams, SharePoint e OneDrive per monitorare l'attività degli utenti e degli amministratori.", - "O365_GRAPH": "Ingeste gli eventi di sicurezza di Microsoft Graph: allerte, incidenti, audit del directory, sign-in, rilevamenti di rischio e log di audit Purview per monitorare identità e attività di minaccia nel tuo tenant.", - "GCP": "Acquisisci i log di audit e attività di Google Cloud Platform per monitorare compute, storage e identità tra i progetti.", - "KASPERSKY": "Acquisisci i rilevamenti di Kaspersky Security Center e la telemetria degli endpoint per correlare l'attività malware nella rete.", - "ESET": "Acquisisci i rilevamenti endpoint e la telemetria di ESET PROTECT per correlare la difesa multilivello dal malware nel tuo parco macchine.", - "BITDEFENDER": "Acquisisci i rilevamenti di Bitdefender GravityZone e la telemetria degli endpoint per correlare le minacce tra i dispositivi aziendali.", - "SENTINEL_ONE": "Acquisisci i rilevamenti endpoint e la telemetria comportamentale di SentinelOne per correlare e investigare le minacce su larga scala.", - "SOPHOS": "Acquisisci i rilevamenti di Sophos Central su endpoint, server, firewall ed e-mail per correlare le minacce in un unico luogo.", - "CROWDSTRIKE": "Acquisisci i rilevamenti su endpoint e workload di CrowdStrike Falcon per correlare l'attività cloud-native delle minacce in UTMStack.", - "CISCO": "Acquisisci il traffico firewall Cisco ASA, VPN e log delle minacce per monitorare la sicurezza perimetrale e gli accessi in UTMStack.", - "MERAKI": "Acquisisci il syslog di firewall e security appliance Cisco Meraki per monitorare il traffico di rete e le minacce gestite nel cloud.", - "FIRE_POWER": "Acquisisci i log di Cisco Firepower NGFW e IPS per monitorare i tentativi di intrusione e l'attività delle minacce al perimetro.", - "CISCO_SWITCH": "Acquisisci il syslog e la telemetria degli switch Cisco per monitorare le prestazioni di rete, le modifiche alla configurazione e la sicurezza.", - "FORTIGATE": "Acquisisci il traffico Fortinet FortiGate NGFW e i log delle minacce per monitorare la sicurezza perimetrale e l'attività di rete.", - "FORTIWEB": "Acquisisci i log WAF di Fortinet FortiWeb per monitorare gli attacchi alle applicazioni web e proteggere servizi e API esposti.", - "SOPHOS_XG": "Acquisisci i log del firewall Sophos XG relativi a web filtering, IPS e VPN per monitorare il traffico di rete e le minacce.", - "PALO_ALTO": "Acquisisci il traffico Palo Alto Networks NGFW e i log delle minacce per monitorare l'utilizzo delle applicazioni e la sicurezza perimetrale.", - "SONIC_WALL": "Acquisisci il traffico SonicWall NGFW e i log delle minacce per monitorare la sicurezza perimetrale e l'attività di rete in UTMStack.", - "PFSENSE": "Acquisisci i log di firewall e router pfSense con unified threat management per monitorare il traffico di rete e le minacce.", - "MIKROTIK": "Acquisisci i log di firewall, routing e wireless di MikroTik RouterOS per monitorare l'attività di rete e la configurazione.", - "AIX": "Raccogli i log di sistema Unix IBM AIX, sicurezza e audit per monitorare l'attività sulle piattaforme IBM Power in UTMStack.", - "AS_400": "Raccogli journal di sistema e di controllo IBM AS/400 (IBM i) per monitorare l'attività degli utenti sulle piattaforme midrange OS/400.", - "ORACLE": "Acquisisci i log di audit di Oracle Database per monitorare query, accessi e attività privilegiate nei tuoi database.", - "SURICATA": "Acquisisci avvisi ed eventi di rete Suricata IDS/IPS per rilevare intrusioni e traffico malevolo sulla rete.", - "DECEPTIVE_BYTES": "Acquisisci gli avvisi di Deceptive Bytes dalla sua piattaforma di inganno attivo degli endpoint per rilevare tempestivamente l'attività degli attaccanti.", - "GITHUB": "Acquisisci i log di audit di GitHub per monitorare l'accesso ai repository, le modifiche al codice e l'attività dell'organizzazione ai fini della sicurezza del codice sorgente.", - "UTMSTACK": "Acquisisci la telemetria SIEM e XDR di UTMStack per monitorare l'integrità della piattaforma, l'attività interna e gli eventi di self-audit.", - "NGINX": { - "name": "Nginx", - "description": "Acquisisci i log di accesso ed errore di Nginx per monitorare l'attività del web server, il traffico del proxy inverso e le richieste dei client." - }, - "APACHE": { - "name": "Apache", - "description": "Acquisisci i log di accesso ed errore di Apache HTTPD per monitorare l'attività del web server e le richieste dei client." - }, - "APACHE2": { - "name": "Apache2", - "description": "Acquisisci i log del web server Apache2 (HTTPD) per monitorare la gestione delle richieste, gli errori e l'accesso sugli host Linux." - }, - "IIS": { - "name": "IIS", - "description": "Acquisisci l'attività di accesso e i file di log di Internet Information Services (IIS) per monitorare il web server di Windows." - }, - "MYSQL": { - "name": "MySQL", - "description": "Acquisisci l'attività di log di MySQL per monitorare query, autenticazione e accesso al data store." - }, - "POSTGRESQL": { - "name": "PostgreSQL", - "description": "Acquisisci i log di PostgreSQL per monitorare query, accesso e attività nei tuoi data store." - }, - "MONGODB": { - "name": "MongoDB", - "description": "Acquisisci l'attività di log di MongoDB per monitorare l'accesso al database documentale, le query e il comportamento dell'applicazione." - }, - "REDIS": { - "name": "Redis", - "description": "Acquisisci l'attività di log e telemetria di Redis per monitorare l'uso del data store in memoria e i workload in tempo reale." - }, - "ELASTICSEARCH": { - "name": "Elasticsearch", - "description": "Acquisisci i log di Elasticsearch per monitorare il motore di ricerca e analisi e i relativi workload applicativi." - }, - "LOGSTASH": { - "name": "Logstash", - "description": "Acquisisci i log delle pipeline Logstash per monitorare la pipeline di elaborazione dati e le trasformazioni degli eventi." - }, - "KIBANA": { - "name": "Kibana", - "description": "Acquisisci i log di Kibana per monitorare il layer di visualizzazione ed esplorazione dati e il relativo utilizzo." - }, - "KAFKA": { - "name": "Apache Kafka", - "description": "Acquisisci i log di Apache Kafka per monitorare le pipeline di streaming in tempo reale, i broker e il flusso dei messaggi." - }, - "NATS": { - "name": "NATS", - "description": "Acquisisci i log di messaging NATS per monitorare il message bus, la connettività e la consegna degli eventi." - }, - "HAPROXY": { - "name": "HAProxy", - "description": "Acquisisci i log di HAProxy per monitorare il bilanciamento del carico, il traffico del proxy e la disponibilità della rete." - }, - "TRAEFIK": { - "name": "Traefik", - "description": "Acquisisci i log di Traefik per monitorare il routing, il bilanciamento del carico e il traffico del proxy tra i workload." - }, - "OSQUERY": { - "name": "osquery", - "description": "Acquisisci i log di OsQuery per monitorare lo stato degli endpoint, le query e l'inventario di sistema tramite richieste in stile SQL." - }, - "SYSLOG": { - "name": "Syslog", - "description": "Invia syslog (RFC 5424/3164) da qualsiasi dispositivo o applicazione all'endpoint del collector per l'acquisizione centralizzata dei log." - }, - "JSON": { - "name": "JSON Input", - "description": "Invia carichi di log in JSON all'endpoint di acquisizione per l'ingest strutturata di eventi da applicazioni e script." - }, - "WINDOWS_SQL_SERVER": { - "name": "SQL Server Event Logs", - "description": "Collect Microsoft SQL Server audit and event records through the Windows Event Log and UTMStack agent." - }, - "WINDOWS_FILE_AUDITING": { - "name": "Windows File Access Auditing", - "description": "Collect Windows file access audit events through the Windows Event Log and UTMStack agent." - }, - "ELASTICsearch": { - "name": "ELASTICsearch", - "description": "Ingesta los registros de Elasticsearch para monitorear el motor de búsqueda y análisis y sus cargas de trabajo de aplicación." - } }, - "edit": { - "title": "Modifica integrazione" - }, - "allCategories": "Tutte le categorie", - "customOnly": "Personalizzato" - }, - "dataProcessing": { - "title": "Elaborazione dati", - "subtitle": "Statistiche di ingestione ed elaborazione: eventi ricevuti, scartati per fase, e le principali origini e tipi.", - "ingestion": { - "title": "Ingestione", - "last24h": "ultime 24 ore", - "noData": "Nessun dato in questa finestra.", - "loadError": "Impossibile caricare le statistiche di ingestione.", - "groupBy": { - "dataSource": "Per origine dati", - "dataType": "Per tipo di dato" - }, - "status": { - "received": "Ricevuti", - "parsing_dropped": "Scartati (parsing)", - "analysis_dropped": "Scartati (analisi)", - "correlation_dropped": "Scartati (correlazione)", - "all": "Tutti gli eventi" - } - }, - "filters": { - "title": "Filtri", - "new": "Nuovo filtro", - "search": "Cerca per percorso…", - "refresh": "Aggiorna", - "retry": "Riprova", - "empty": "Nessun filtro corrisponde.", - "loadError": "Impossibile caricare i filtri.", - "toggleError": "Impossibile cambiare lo stato del filtro", - "system": "Sistema", - "custom": "Personalizzato", - "systemReadonly": "I filtri di sistema sono di sola lettura", - "view": "Visualizza", - "edit": "Modifica", - "ownership": { - "all": "Tutti", + "parsingFilters": { + "title": "Pipeline", + "subtitle": "Pipeline YAML applicate ai log durante l'analisi in fase di ingestione.", + "new": "Nuova pipeline", + "search": "Cerca pipeline…", + "refresh": "Aggiorna", + "view": "Vedi", "system": "Sistema", - "custom": "Personalizzati" - }, - "state": { - "all": "Tutti", - "active": "Attivi", - "inactive": "Inattivi" - }, - "col": { - "filter": "Filtro", - "type": "Tipo", - "active": "Attivo", - "actions": "Azioni" - }, - "pageInfo": "{{from}}–{{to}} di {{count}}" - }, - "editor": { - "createTitle": "Nuovo filtro", - "editTitle": "Modifica filtro", - "viewTitle": "Visualizza filtro", - "relPath": "Percorso", - "relPathHint": "Cartella + file, es. syslog/mio-filtro.yaml", - "content": "Pipeline (YAML)", - "contentHint": "I passaggi vengono eseguiti in ordine: grok, rename, delete, plugin dynamic, …", - "save": "Salva", - "saving": "Salvataggio…", - "saved": "Filtro salvato", - "saveError": "Impossibile salvare il filtro", - "cancel": "Annulla", - "delete": "Elimina", - "deleteConfirm": "Eliminare questo filtro?", - "deleted": "Filtro eliminato", - "deleteError": "Impossibile eliminare il filtro" - }, - "kpi": { - "received": "Ricevuti", - "dropped": "Scartati", - "dropRate": "{{rate}}% di scarto", - "stored": "Archiviati", - "throughput": "Throughput", - "perMin": "{{value}}/min", - "survival": "{{rate}}% mantenuti" - }, - "section": { - "overTime": "Eventi nel tempo", - "top": "Top", - "dropReasons": "Motivi di scarto" - }, - "live": { - "auto": "Auto" - }, - "pipeline": { - "title": "Pipeline di ingestione", - "stages": { - "received": "Ricevuti", - "parsed": "Analizzati (parse)", - "analyzed": "Analizzati", - "stored": "Archiviati" - } - }, - "chart": { - "title": "Throughput nel tempo", - "received": "Ricevuti", - "dropped": "Scartati" - }, - "donut": { - "title": "Composizione scarti", - "dropped": "scartati" - }, - "breakdown": { - "title": "Top sorgenti e tipi", - "bars": "Barre", - "treemap": "Treemap", - "showAll": "Mostra tutti i {{count}}", - "showLess": "Mostra meno", - "lastSeen": "Visto l’ultima volta", - "ago": "{{time}} fa" - } - }, - "datasources": { - "limitBanner": { - "title": "Limite di datasource superato.", - "message": "Hai {{count}} datasource ma la tua licenza copre {{limit}}. I log dei datasource oltre il limite vengono scartati.", - "cta": "Gestisci licenza", - "dismiss": "Ignora" - }, - "title": "Origini dati", - "total": "{{count}} in totale", - "subtitle": "Agenti, integrazioni e origini dirette che inviano eventi. Lo stato è derivato dall'ultima volta che ogni origine è stata vista.", - "connectSource": "Collega un'origine", - "loading": "Caricamento origini dati…", - "loadFailed": "Impossibile caricare le origini dati.", - "retry": "Riprova", - "none": "Nessuna origine corrisponde a questa vista.", - "ingestion": { - "title": "Ingestione", - "received": "eventi ricevuti", - "none": "Nessuna ingestione nelle ultime 24 ore.", - "ago24h": "24h fa", - "now": "ora" - }, - "usage": { - "title": "Origini dati", - "ofUnlimited": "di illimitato", - "ofLimit": "di {{limit}}", - "overLimit": "Oltre il limite della licenza — i dati oltre il limite sono a rischio.", - "configured": "configurate" - }, - "tabs": { - "all": "Tutte", - "agent": "Agenti", - "puller": "Integrazioni", - "direct": "Dirette", - "offline": "Offline" - }, - "toolbar": { - "searchPlaceholder": "Cerca per nome…", - "list": "Elenco", - "cards": "Schede", - "refresh": "Aggiorna" - }, - "labels": { - "filteredBy": "Filtrato per label", - "add": "Aggiungi label…", - "addFirst": "Aggiungi un label…", - "hint": "Scrivi un label e premi Invio per aggiungerlo. Le modifiche vengono salvate automaticamente." - }, - "status": { - "live": "Attiva", - "idle": "Inattiva", - "offline": "Offline" - }, - "kind": { - "agent": "Agente", - "puller": "Integrazione", - "direct": "Diretta" - }, - "cols": { - "source": "Origine", - "type": "Tipo", - "status": "Stato", - "events24h": "Eventi 24h", - "lastSeen": "Vista l'ultima volta" - }, - "time": { - "justNow": "proprio ora", - "minutesAgo": "{{count}}m fa", - "hoursAgo": "{{count}}h fa", - "daysAgo": "{{count}}g fa" + "user": "Personalizzato", + "loading": "Caricamento pipeline…", + "loadError": "Impossibile caricare le pipeline.", + "retry": "Riprova", + "empty": "Nessuna pipeline corrisponde a questa vista.", + "tabs": { + "all": "Tutti", + "active": "Attivi", + "inactive": "Inattivi", + "system": "Sistema", + "user": "Personalizzati" + }, + "cols": { + "filter": "Pipeline", + "type": "Tipo", + "active": "Attivo", + "dataTypes": "Tipi di dati", + "order": "Ordine", + "moveUp": "Sposta su", + "moveDown": "Sposta giù", + "actions": "Azioni" + }, + "editor": { + "titleNew": "Nuova pipeline", + "titleEdit": "Modifica pipeline", + "titleSystem": "Pipeline (sistema)", + "name": "Nome", + "namePlaceholder": "La mia pipeline personalizzata", + "nameHint": "Verrà salvato come {{file}}", + "namePending": "Scegli un nome — diventerà il nome del file.", + "content": "Contenuto (YAML pipeline)", + "contentHint": "Una definizione YAML pipeline: valida.", + "readOnly": "Pipeline di sistema — in sola lettura. Puoi solo abilitarla o disabilitarla.", + "save": "Salva", + "saving": "Salvataggio…", + "delete": "Elimina", + "confirmDelete": "Conferma eliminazione", + "cancel": "Annulla", + "test": "Test" + }, + "toast": { + "saved": "Pipeline salvata", + "saveError": "Salvataggio della pipeline non riuscito", + "deleted": "Pipeline eliminata", + "deleteError": "Eliminazione della pipeline non riuscita", + "activateError": "Modifica dello stato della pipeline non riuscita", + "nameRequired": "Il nome è obbligatorio", + "contentRequired": "Il contenuto è obbligatorio", + "orderError": "Impossibile modificare l'ordine della pipeline" + }, + "visual": { + "visualTab": "Visuale", + "codeTab": "Codice", + "codeOnly": "Passa al Codice — questo contenuto non può essere mostrato visivamente.", + "cantParse": "Impossibile aprire l'editor visuale: {{error}}", + "dataTypes": "Tipi di dati", + "steps": "Passaggi", + "noSteps": "Ancora nessun passaggio.", + "addStep": "Aggiungi passaggio:", + "removeStep": "Rimuovi passaggio", + "moveUp": "Su", + "moveDown": "Giù", + "whereHint": "condizione opzionale (CEL)", + "addValue": "Aggiungi valore", + "addPattern": "Aggiungi pattern", + "rawHint": "Questo processore si modifica come YAML grezzo.", + "rawNotMap": "Deve essere un insieme di campi chiave: valore.", + "dataTypesPick": "Scegli tipi di dati", + "dataTypesSearch": "Cerca tipi di dati…", + "dataTypesNone": "Nessun tipo di dato", + "dataTypesAdd": "Aggiungi \"{{value}}\"", + "insertPattern": "Inserisci pattern regex", + "patternSearch": "Cerca pattern…", + "patternNone": "Nessun pattern", + "newPattern": "Nuovo pattern…", + "createInsert": "Crea e inserisci", + "patternCreated": "Pattern \"{{name}}\" creato", + "patternCreateError": "Creazione del pattern non riuscita", + "patternIdInvalid": "L'ID del pattern deve iniziare con una lettera o _ e usare solo lettere, cifre o _", + "patternDefRequired": "La definizione è obbligatoria", + "parameters": "Parametri", + "paramsKey": "Chiave", + "paramsValue": "Valore", + "entry": "Vocetta {{n}}", + "order": "ordine {{n}}", + "orderLabel": "Ordine", + "removeEntry": "Rimuovi vocetta", + "addEntry": "Aggiungi vocetta di pipeline", + "collapse": "Comprimi", + "expand": "Espandi", + "splitHint": "Vacío equivale a un espacio por defecto — en el YAML siempre aparece como fieldSplit: \" \"." + }, + "allDataTypes": "Tutti i tipi di dati", + "testPipeline": "Test pipeline" + }, + "soar": { + "title": "SOAR", + "subtitle": "Flussi di risposta automatica: le condizioni corrispondono a un alert, i comandi vengono eseguiti sull'agente.", + "comingSoon": "Prossimamente", + "console": { + "loading": "Caricamento agenti…", + "loadError": "Impossibile caricare gli agenti.", + "pickAgent": "Seleziona un agente", + "pickAgentHint": "Scegli un agente dall'elenco per aprire la sua console interattiva.", + "lockedAgent": "Controllo remoto disattivato" + }, + "search": "Cerca flussi…", + "refresh": "Aggiorna", + "new": "Nuovo flusso", + "view": "Vedi", + "system": "Sistema", + "loading": "Caricamento flussi…", + "loadError": "Impossibile caricare i flussi.", + "retry": "Riprova", + "empty": "Nessun flusso corrisponde a questa vista.", + "templates": { + "title": "Nuovo flusso", + "subtitle": "Scegli un modello di azione o parti da zero.", + "loading": "Caricamento modelli…", + "loadError": "Impossibile caricare i modelli.", + "empty": "Nessun modello disponibile.", + "cancel": "Annulla", + "scratch": "Parti da zero" + }, + "tabs": { + "flows": "Flussi", + "executions": "Cronologia esecuzioni", + "all": "Tutti", + "active": "Attivi", + "inactive": "Inattivi", + "system": "Sistema", + "user": "Personalizzati" + }, + "cols": { + "flow": "Flusso", + "platform": "Piattaforma", + "conditions": "Condizioni", + "commands": "Comandi", + "active": "Attivo", + "lastRun": "Ultima esecuzione", + "failedRuns_one": "{{count}} esecuzione fallita", + "failedRuns_other": "{{count}} esecuzioni fallite" + }, + "operator": { + "IS": "è", + "IS_NOT": "non è", + "CONTAINS": "contiene", + "NOT_CONTAINS": "non contiene", + "EXISTS": "esiste", + "NOT_EXISTS": "non esiste", + "START_WITH": "inizia con", + "NOT_START_WITH": "non inizia con", + "ENDS_WITH": "termina con", + "NOT_ENDS_WITH": "non termina con", + "IS_ONE_OF": "è uno di", + "IS_NOT_ONE_OF": "non è uno di" + }, + "toast": { + "created": "Flusso creato", + "saved": "Flusso salvato", + "saveError": "Salvataggio del flusso non riuscito", + "deleted": "Flusso eliminato", + "deleteError": "Eliminazione del flusso non riuscita", + "activateError": "Modifica dello stato del flusso non riuscita" + }, + "editor": { + "createTitle": "Nuovo flusso", + "visualTab": "Visuale", + "codeTab": "Codice", + "name": "Nome", + "description": "Descrizione", + "conditions": "Condizioni", + "conditionsHint": "Il flusso viene eseguito quando un alert soddisfa TUTTE queste condizioni.", + "field": "campo", + "value": "valore", + "valueList": "valori separati da virgola", + "addCondition": "Aggiungi condizione", + "commands": "Comandi", + "commandsHint": "Eseguiti in ordine sull'agente. Usa $(field.path) per i valori dell'alert e $[variables.NAME] per le variabili salvate.", + "addCommand": "Aggiungi comando", + "templatesButton": "Comandi comuni", + "templates": { + "isolate": "Isola dalla rete", + "shutdown": "Spegni macchina", + "killProcess": "Termina processo", + "logout": "Disconnetti utente", + "disableUser": "Disabilita utente", + "blockIp": "Blocca IP", + "restart": "Riavvia la macchina", + "uninstall": "Disinstalla applicazione" + }, + "connector": { + "always": "sempre", + "success": "se riuscito", + "failure": "se fallito" + }, + "agentPlatform": "Piattaforma dell'agente", + "shell": "Shell", + "shellAuto": "auto", + "whereToRun": "Dove eseguire", + "run": { + "all": "Tutti gli agenti", + "specific": "Un agente", + "except": "Tutti tranne", + "allHint": "Viene eseguito su ogni agente che corrisponde a questa piattaforma." + }, + "selectAgentPlaceholder": "Seleziona un agente…", + "excludedAgentsHint": "digita un hostname e premi Invio", + "save": "Salva", + "delete": "Elimina", + "confirmDelete": "Conferma eliminazione", + "cancel": "Annulla", + "yamlError": "Impossibile applicare lo YAML: {{error}}", + "nameRequired": "Il nome è obbligatorio", + "conditionsRequired": "È richiesta almeno una condizione con un campo", + "commandsRequired": "È richiesto almeno un comando", + "httpUrlInvalid": "Il nodo HTTP \"{{id}}\" ha un URL non valido — deve essere un URL http(s) valido.", + "httpBodyInvalid": "Il corpo del nodo HTTP \"{{id}}\" non è JSON valido: {{error}}", + "incidentNameRequired": "Il nodo incidente \"{{id}}\" richiede un nome.", + "mailToRequired": "Il nodo e-mail \"{{id}}\" richiede almeno un destinatario.", + "mailAddressInvalid": "Il nodo e-mail \"{{id}}\" contiene un indirizzo {{field}} non valido: {{address}}.", + "mailSubjectRequired": "Il nodo e-mail \"{{id}}\" richiede un oggetto.", + "identityModalTitle": "Dettagli del flusso", + "platformRequired": "La piattaforma dell'agente è obbligatoria", + "nameLabel": "Nome", + "namePlaceholder": "Nome del flusso", + "descriptionLabel": "Descrizione", + "descriptionHint": "Cosa fa questo flusso? (opzionale)", + "when": "Quando", + "whenTitle": "Un alert soddisfa tutte queste condizioni", + "on": "Su", + "onTitle": "L'agente corrispondente", + "thenRun": "Allora esegui", + "thenTitle": "Questi comandi, in ordine", + "selectField": "Scegli un campo…", + "selectPlatform": "Scegli una piattaforma…", + "searchAgents": "Cerca agenti…", + "noAgents": "Nessun agente", + "insertInto": "Inserisci nel comando {{n}}:", + "insertField": "Campo dell'alert", + "variables": "Variabili", + "canvas": { + "node": "Nodo", + "deleteNode": "Elimina nodo", + "id": "ID", + "kind": "Tipo", + "executor": "Esecutore", + "commandLabel": "Comando", + "paramsJson": "Parametri (JSON)", + "dragToResize": "Trascina per ridimensionare", + "templatesLabel": "Modelli", + "templatesNeedPlatform": "Seleziona prima la piattaforma di destinazione", + "handlesHint": "Trascina dalla maniglia verde (in basso a sinistra) per on_success e da quella rossa (in basso a destra) per on_error. Più connessioni = parallelo. Più connessioni verso lo stesso nodo = AND-join.", + "invalidJson": "JSON non valido", + "hidePalette": "Nascondi tavolozza", + "hideInspector": "Nascondi ispettore", + "paletteLabel": "Tavolozza", + "nodeShort": "Nodo", + "showPanel": "Mostra {{name}}", + "platform": "Piattaforma", + "shell": "Shell", + "any": "qualsiasi", + "auto": "auto", + "runOn": "Esegui su", + "runAutoTitle": "Esegue sull'host che ha generato l'allerta", + "runSpecificTitle": "Fissa a un host (o un modello come $(alert.foo))", + "runExceptTitle": "Esegue sull'host che ha generato l'allerta, escludendo quelli nella lista", + "runAutoLabel": "sorgente allerta", + "runSpecificLabel": "un host", + "runExceptLabel": "tutti tranne", + "runAutoHint": "Esegue su $(alert.dataSource) — l'host che ha generato l'allerta.", + "pickHost": "scegli un host…", + "orTemplateHint": "O digita un modello — $(alert.field) viene risolto ad ogni esecuzione.", + "addExclusion": "aggiungi esclusione", + "searchAgents": "cerca agenti…", + "noAgents": "nessun agente", + "insertField": "Inserisci campo", + "alert": "Allerta", + "wholeOutput": "output completo (modifica il percorso)", + "noAncestorsHint": "Nessun antenato di arricchimento — aggiungi un nodo di arricchimento a monte per esporre qui il suo output.", + "inserts": "inserisce", + "conditionalHint": "Tutte le condizioni devono corrispondere. Corrispondenza → ramo di successo (verde); mancata → ramo di errore (rosso).", + "http": { + "url": "URL", + "urlInvalid": "URL http(s) non valido.", + "method": "Metodo", + "body": "Corpo (JSON)", + "bodyInvalid": "JSON non valido", + "headers": "Intestazioni HTTP", + "params": "Parametri di query", + "key": "Chiave", + "value": "Valore", + "addHeader": "Aggiungi intestazione", + "addParam": "Aggiungi parametro" + }, + "incident": { + "name": "Nome dell'incidente", + "namePlaceholder": "Es. Accesso sospetto su $(alert.dataSource)", + "description": "Descrizione", + "descriptionPlaceholder": "Contesto facoltativo per i risponditori. I template come $(alert.name) vengono interpolati." + }, + "llm": { + "prompt": "Prompt", + "hint": "Al modello è imposto di rispondere sempre con un unico oggetto JSON con la proprietà \"result\"; il backend garantisce questa forma anche se il modello devia. I nodi figli lo consultano tramite $({{nodeId}}.result) o campi specifici." + }, + "mail": { + "to": "A (separati da virgola)", + "cc": "CC (separati da virgola, opzionale)", + "addressInvalid": "Indirizzo e-mail non valido: {{address}}", + "subject": "Oggetto", + "subjectPlaceholder": "Es. Allarme su $(alert.dataSource)", + "body": "Corpo", + "bodyPlaceholder": "Contenuto del messaggio. I template come $(alert.name) vengono interpolati." + }, + "notify": { + "level": "Level", + "message": "Message", + "messagePlaceholder": "Notification text. Templates like $(alert.name) are interpolated." + } + } + }, + "executions": { + "search": "Cerca per ID alert…", + "all": "Tutte", + "loading": "Caricamento esecuzioni…", + "loadError": "Impossibile caricare le esecuzioni.", + "retry": "Riprova", + "empty": "Ancora nessuna esecuzione.", + "cols": { + "status": "Stato", + "flow": "Flusso", + "command": "Comando / Acción", + "agent": "Agente", + "date": "Data", + "retries": "Tentativi", + "node": "Nodo" + }, + "filters": { + "source": "Origine", + "allSources": "Tutte le origini" + }, + "manual": "Console interattiva" + }, + "executionStatus": { + "WAITING": "In attesa", + "PENDING": "In coda", + "EXECUTING": "In esecuzione", + "EXECUTED": "Eseguito", + "FAILED": "Fallito", + "DEAD": "Non raggiungibile" + }, + "executionOrigin": { + "FLOW": "Flusso", + "MANUAL": "Manuale" + }, + "nonExecutionCause": { + "AGENT_OFFLINE": "Agente offline", + "AGENT_NOT_FOUND": "Agente non trovato", + "UNKNOWN": "Sconosciuto" + }, + "kpi": { + "flows": "Flussi totali", + "active": "Attivi", + "runs24h": "Esecuzioni (24h)", + "failed24h": "Fallite (24h)" + }, + "neverRun": "mai", + "create": { + "title": "Nuovo flusso", + "modeManual": "Crea manualmente", + "modeAi": "Con IA", + "aiLocked": "Abilita SOC-AI e configuralo per usarlo.", + "name": "Nome del flusso", + "namePlaceholder": "es. Blocca IP in caso di fallimenti ripetuti", + "aiDescriptionLabel": "Cosa deve fare questo flusso?", + "aiDescriptionPlaceholder": "es. In caso di alert critico, cerca l'IP di origine nell'intelligence sulle minacce e bloccalo sul firewall", + "aiCreate": "Crea con IA", + "manualContinue": "Continua" + } }, - "drawer": { - "loading": "Caricamento…", - "loadFailed": "Impossibile caricare l'origine dati.", - "statsIdentity": "Statistiche e identità", - "metadata": "Metadati", - "labelsSection": "Labels", - "dangerZone": "Zona pericolosa", - "rows": { - "events24h": "Eventi 24h", - "lastSeen": "Vista l'ultima volta", - "discovered": "Scoperta", - "kind": "Tipo di origine", - "dataType": "Tipo di dato", - "ip": "IP", - "id": "ID" - }, - "dangerText": "L'eliminazione rimuove questa origine dal registro. Gli eventi storici restano consultabili nel Log Explorer; se l'origine continua a inviare dati, verrà riscoperta.", - "delete": "Elimina origine", - "confirmDelete": "Conferma eliminazione", - "cancel": "Annulla", - "viewLogs": "Visualizza log", - "trend": "Andamento ingestione", - "noTrend": "Nessun evento ricevuto in questo intervallo", - "logGap": "Ultimo evento {{since}} — possibile interruzione dei log" + "compliance": { + "title": "Compliance", + "subtitle": "Valuta la tua postura rispetto ai framework di sicurezza — vedi quali controlli sono soddisfatti e quali no.", + "comingSoon": "Prossimamente.", + "tabs": { + "frameworks": "Framework", + "schedule": "Pianificazione", + "controls": "Controlli" + }, + "search": "Cerca framework…", + "refresh": "Refresh", + "loading": "Caricamento framework…", + "loadError": "Could not load reports", + "retry": "Riprova", + "empty": "Nessun framework corrisponde.", + "notEvaluated": "Non valutato", + "controlsCount": "{{n}} controlli", + "enabledLabel": "Attivo", + "runReport": "Esegui report", + "backToFrameworks": "Torna ai framework", + "statusAuto": "Auto (valutato)", + "overrideError": "Impossibile aggiornare lo stato", + "noteError": "Impossibile salvare la nota", + "notes": { + "title": "Note", + "placeholder": "Aggiungi una nota…", + "save": "Salva", + "cancel": "Annulla" + }, + "reasonModal": { + "title": "Motivazione richiesta", + "description": "Indica il motivo del cambio di stato. Verrà registrato.", + "label": "Motivazione", + "placeholder": "Spiega perché stai cambiando lo stato di questo controllo…", + "confirm": "Conferma cambio", + "cancel": "Annulla" + }, + "coverageLabel": "Copertura", + "activityLabel": "Attività", + "evidenceLabel": "Evidenza", + "seeMore": "Mostra di più", + "seeLess": "Mostra meno", + "evaluating": "Valutazione del framework…", + "complianceScore": "Punteggio di conformità", + "generatedAt": "Generato {{date}}", + "reportError": "Impossibile generare il report.", + "coverage": "{{n}} regole", + "activity": "{{n}} avvisi", + "status": { + "COMPLIANT": "Conforme", + "NON_COMPLIANT": "Non conforme", + "AT_RISK": "A rischio", + "NOT_COVERED": "Non coperto", + "OUT_OF_SCOPE": "Fuori ambito", + "PENDING": "In sospeso", + "label": "Stato", + "NOT_EVALUATED": "Not evaluated" + }, + "toast": { + "toggleError": "Impossibile cambiare lo stato del framework", + "reportGenerated": "Report generato", + "reportError": "Impossibile generare il report" + }, + "schedule": { + "new": "Nuova pianificazione", + "loading": "Caricamento pianificazioni…", + "loadError": "Impossibile caricare le pianificazioni.", + "empty": "Ancora nessuna pianificazione.", + "edit": "Modifica", + "delete": "Elimina", + "newTitle": "Nuova pianificazione", + "editTitle": "Modifica pianificazione", + "framework": "Framework", + "cadenceLabel": "Cadenza", + "cronHint": "Cron a 5 campi (min ora giorno mese giornoSettimana).", + "recipientsHint": "Email separate da virgola. Lascia vuoto per salvare solo lo snapshot.", + "save": "Salva", + "cancel": "Annulla", + "frameworkRequired": "Il framework è obbligatorio", + "cronRequired": "La pianificazione (cron) è obbligatoria", + "cadence": { + "daily": "Giornaliera", + "weekly": "Settimanale", + "monthly": "Mensile", + "custom": "Personalizzata" + }, + "toast": { + "saved": "Pianificazione salvata", + "saveError": "Impossibile salvare la pianificazione", + "deleted": "Pianificazione eliminata", + "deleteError": "Impossibile eliminare la pianificazione" + }, + "to": "To", + "cc": "Cc", + "toRequired": "At least one recipient is required", + "windowDays": "Reporting window (days)", + "windowDaysShort": "over {{days}}d", + "windowDaysHint": "How far back the report counts. Independent of how often it runs." + }, + "frameworks": { + "new": "Nuovo framework", + "edit": "Modifica", + "createTitle": "Nuovo framework", + "visualTab": "Visuale", + "codeTab": "Codice", + "key": "Chiave", + "name": "Nome", + "description": "Descrizione", + "source": "Fonte", + "sections": "Sezioni", + "sectionKey": "chiave sezione", + "sectionName": "Nome della sezione", + "requirements": "Requisiti", + "reqId": "id req.", + "reqName": "Nome del requisito", + "addSection": "Aggiungi sezione", + "addRequirement": "Aggiungi requisito", + "satisfiedBy": "soddisfatto dai controlli", + "searchControls": "Cerca controlli…", + "noControls": "Nessun controllo", + "save": "Salva", + "delete": "Elimina", + "confirmDelete": "Conferma eliminazione", + "cancel": "Annulla", + "yamlError": "Impossibile applicare lo YAML: {{error}}", + "keyRequired": "La chiave è obbligatoria", + "nameRequired": "Il nome è obbligatorio", + "toast": { + "created": "Framework creato", + "saved": "Framework salvato", + "saveError": "Impossibile salvare il framework", + "deleted": "Framework eliminato", + "deleteError": "Impossibile eliminare il framework" + }, + "createControl": "Crea nuovo controllo…", + "createNamed": "Crea controllo \"{{name}}\"…" + }, + "controls": { + "search": "Cerca controlli…", + "allFamilies": "Tutte le famiglie", + "new": "Nuovo controllo", + "loading": "Caricamento controlli…", + "loadError": "Impossibile caricare i controlli.", + "empty": "Nessun controllo corrisponde.", + "showingOf": "Visualizzati {{shown}} di {{total}}", + "id": "ID", + "name": "Nome", + "family": "Famiglia", + "familyName": "Famiglia", + "scope": "Ambito", + "source": "Origine", + "notInLibrary": "Controllo non trovato in libreria", + "scopeOpt": { + "data": "Dati", + "governance": "Governance" + }, + "strategy": "Strategia", + "statement": "Enunciato", + "remediation": "Rimedio", + "checks": "Verifiche", + "checksHint": "Ogni verifica esegue una query SQL su OpenSearch e applica una regola per decidere superato/fallito.", + "checkKey": "chiave", + "checkName": "Nome della verifica", + "rule": { + "MIN_HITS_REQUIRED": "Risultati minimi richiesti", + "THRESHOLD_MAX": "Soglia massima" + }, + "ruleNone": "Nessuna regola", + "ruleValue": "valore", + "addCheck": "Aggiungi verifica", + "createTitle": "Nuovo controllo", + "visualTab": "Visuale", + "codeTab": "Codice", + "save": "Salva", + "delete": "Elimina", + "confirmDelete": "Conferma eliminazione", + "cancel": "Annulla", + "yamlError": "Impossibile applicare lo YAML: {{error}}", + "idRequired": "L'ID è obbligatorio", + "nameRequired": "Il nome è obbligatorio", + "anyDataType": "Any data type", + "addFilter": "Add filter", + "filterField": "log.eventCode", + "filterValue": "value", + "filterValues": "a, b, c", + "toast": { + "created": "Controllo creato", + "saved": "Controllo salvato", + "saveError": "Impossibile salvare il controllo", + "deleted": "Controllo eliminato", + "deleteError": "Impossibile eliminare il controllo" + } + }, + "doc": { + "title": "Report di conformità", + "print": "Stampa / PDF", + "controlsEvaluated": "{{n}} controlli valutati", + "executiveSummary": "Sintesi esecutiva", + "bySection": "Risultati per sezione", + "footer": "{{framework}} — Report di conformità generato {{date}} · {{brand}}", + "download": "Scarica PDF", + "downloadError": "Impossibile scaricare il PDF", + "error": "Impossibile generare il PDF", + "building": "Generazione del documento…" + }, + "locked": { + "badge": "Enterprise", + "upgrade": "Passa a Enterprise", + "upsell": "Questo framework/controllo richiede l'edizione Enterprise." + }, + "run": "Run evaluation", + "runError": "Evaluation failed", + "noReportYet": "This framework has not been evaluated yet.", + "window": "window {{from}} → {{to}}", + "scoredOver": "{{compliant}} of {{evaluated}} requirements met · {{total}} in the framework", + "editStale": "Recorded when the engine said {{was}}; it now says {{now}}", + "checkResults": "Check results", + "verdict": "Recorded verdict", + "engineSaid": "engine said", + "hits": "hits", + "noDataFor": "no {{dataType}} data in the window", + "setStatus": "Set status", + "outcome": { + "PASSED": "Passed", + "FAILED": "Failed", + "NOT_APPLICABLE": "No data", + "ERROR": "Error" + }, + "system": "Di sistema", + "addNote": "Aggiungi nota", + "noteModal": { + "title": "Nota", + "description": "Registrata nel report. Non cambia lo stato del controllo.", + "placeholder": "Rimedio in corso — ticket OPS-4412." + }, + "history": { + "title": "Score nel tempo", + "score": "Score di conformità", + "coverage": "Valutati", + "error": "Impossibile caricare lo storico" + } }, - "toast": { - "labelsUpdated": "Labels aggiornati", - "labelsFailed": "Impossibile aggiornare i labels", - "deleted": "Origine eliminata", - "deleteFailed": "Eliminazione non riuscita" + "socAi": { + "title": "Configurazione SOC-AI", + "subtitle": "Configura l'agente AI che esegue il triage degli alert e alimenta l'assistente operativo.", + "section": { + "connection": "Modello e connessione", + "auth": "Autenticazione", + "behavior": "Comportamento del triage degli alert", + "advanced": "Avanzate" + }, + "usage": { + "title": "Utilizzo", + "chat": "Completamenti chat (oggi)", + "unavailable": "L'utilizzo non è ancora disponibile.", + "resetsIn": "Si azzera tra {{time}}" + }, + "provider": { + "label": "Provider", + "hint": "Seleziona il formato di trasmissione. Qualsiasi opzione diversa da Anthropic usa l'API compatibile con OpenAI." + }, + "model": { + "label": "Modello", + "hint": "Identificatore del modello esposto dal provider.", + "customOption": "Modello personalizzato…", + "customPlaceholder": "Inserisci un ID modello" + }, + "url": { + "label": "URL API", + "hint": "Lascia vuoto per usare l'endpoint predefinito del provider." + }, + "apiKey": { + "label": "Chiave API", + "hint": "Credenziale inviata al provider.", + "setHint": "Una chiave è memorizzata. Lascia vuoto per mantenerla." + }, + "authType": { + "label": "Tipo di autenticazione", + "hint": "Come vengono inviate le credenziali al tuo gateway.", + "options": { + "apiKey": "API Key", + "bearer": "Bearer", + "customHeaders": "Header personalizzati", + "none": "Nessuna" + } + }, + "authHeaderName": { + "label": "Nome header di autenticazione", + "hint": "Header che trasporta la chiave (es. api-key per Azure)." + }, + "authToken": { + "label": "Token Bearer", + "hint": "Credenziale inviata al provider.", + "setHint": "È memorizzato un token. Lascia vuoto per mantenerlo." + }, + "customHeaders": { + "label": "Header personalizzati", + "hint": "Header aggiuntivi inviati a ogni richiesta. I valori sono cifrati; \"*****\" mantiene quello memorizzato.", + "keyPlaceholder": "Nome header", + "valuePlaceholder": "Valore", + "addRow": "Aggiungi header", + "remove": "Rimuovi header" + }, + "maxTokens": { + "label": "Token massimi", + "hint": "Numero massimo di token per risposta dell'LLM." + }, + "maxToolIterations": { + "label": "Iterazioni massime degli strumenti", + "hint": "Limite al ciclo dell'agente piano -> strumento -> osservazione." + }, + "autoAnalyze": { + "label": "Analisi automatica degli alert", + "hint": "Esegui il triage degli alert in arrivo in tempo reale." + }, + "allowIncidents": { + "label": "Consenti la gestione degli incident", + "hint": "L'agente di triage può creare o aggiornare incident quando ritiene che un alert lo giustifichi." + }, + "changeAlertStatus": { + "label": "Modifica stato degli alert", + "hint": "Consenti all'agente di impostare lo stato di un alert durante il triage." + }, + "automaticIncidentCreation": { + "label": "Crea incident", + "hint": "Consenti all'agente di aprire incident dagli alert sottoposti a triage." + }, + "allowedWriteTools": { + "label": "Strumenti di scrittura consentiti", + "hint": "Un nome di strumento MCP per riga che l'agente di triage può usare (es. alerts.update_status). Le note sono sempre consentite." + }, + "save": "Salva configurazione", + "saving": "Verifica e salvataggio in corso...", + "saved": "Configurazione SOC-AI salvata", + "saveError": "Impossibile salvare la configurazione", + "loadError": "Impossibile caricare la configurazione", + "modelRequired": "Il modello è obbligatorio", + "applyTags": { + "label": "Applica etichette", + "hint": "Consenti all'agente di etichettare gli alert durante il triage." + }, + "note": { + "azure": "Incolla l'endpoint completo del tuo deployment Azure come URL; il modello è il nome del tuo deployment. L'autenticazione usa l'header api-key.", + "ollama": "Punta l'URL al tuo host Ollama. Non è necessaria alcuna chiave API per un'istanza locale.", + "custom": "Qualsiasi endpoint compatibile con OpenAI. Imposta l'URL, l'autenticazione e gli eventuali header aggiuntivi richiesti dal tuo gateway.", + "threatwinds": "Usa automaticamente la tua licenza UTMStack — non serve una API key. Fatturato tramite il tuo abbonamento ThreatWinds." + }, + "chat": { + "title": "Assistente SOC", + "dashboardCreateTitle": "Creazione dashboard", + "empty": "Chiedi qualsiasi cosa sui tuoi alert, sulle rilevazioni o sulla console — posso investigare e agire sul SIEM.", + "tryPrefix": "Prova", + "suggestion": "quanti alert aperti, raggruppati per avversario?", + "placeholder": "Fai una domanda…", + "ask": "Chiedi", + "send": "Invia", + "collapse": "Comprimi", + "expand": "Espandi", + "clear": "Cancella conversazione", + "close": "Chiudi", + "copy": "Copia", + "copied": "Copiato", + "errorGeneric": "Si è verificato un errore.", + "errorUnreachable": "Impossibile raggiungere l'assistente.", + "compacting": "Compattazione del contesto…", + "dashboardEditTitle": "Editor dashboard", + "editingDashboard": "Modifica di: {{name}}", + "soarEditTitle": "Editor di flussi SOAR", + "soarCreateTitle": "Crea un flusso SOAR", + "editingFlow": "Modifica del flusso: {{name}}" + }, + "focus": { + "alert": "Avviso", + "incident": "Incidente", + "remove": "Smetti di condividere con l'assistente" + }, + "inheritance": { + "inherited": "Segue l'impostazione predefinita dell'istanza. Salvando, questo tenant avrà la propria.", + "own": "Questo tenant ha una configurazione propria.", + "revert": "Torna a quella dell'istanza", + "reverting": "Ripristino…", + "reverted": "Ora segue l'impostazione dell'istanza" + }, + "allowance": { + "title": "Consumo IA oggi", + "ofLimit": "di {{limit}} richieste", + "denied": "richieste — l'IA non è disponibile per questo tenant", + "hint": "Deciso da chi gestisce l'istanza. Si azzera a mezzanotte UTC." + } }, - "sensitivity": { - "section": "Sensibilità dell'asset", - "hint": "Criticità di business (CIA, 0–3) di questo asset. Gli alert diretti al suo host/IP sono pesati con questi valori.", - "saved": "Sensibilità aggiornata", - "failed": "Aggiornamento della sensibilità non riuscito", - "save": "Salva", - "confidentiality": "Riservatezza", - "integrity": "Integrità", - "availability": "Disponibilità", - "levels": { - "0": "Nessuna", - "1": "Bassa", - "2": "Media", - "3": "Alta" - } + "taggingRules": { + "title": "Regole di etichettatura", + "subtitle": "Etichetta automaticamente gli alert che soddisfano le condizioni.", + "new": "Nuova regola", + "refresh": "Aggiorna", + "empty": "Nessuna regola di etichettatura.", + "loadError": "Impossibile caricare le regole di etichettatura.", + "retry": "Riprova", + "deleteConfirm": "Eliminare la regola \"{{name}}\"? Gli alert futuri che soddisfano le sue condizioni non verranno più etichettati.", + "toolbar": { + "search": "Cerca per nome regola…", + "allTags": "Tutte le etichette" + }, + "table": { + "rule": "Regola", + "tags": "Etichette", + "conditions": "Condizioni", + "modifiedBy": "Modificato da", + "modifiedDate": "Modificato" + }, + "drawer": { + "createTitle": "Nuova regola di etichettatura", + "edit": "Modifica", + "delete": "Elimina", + "save": "Salva", + "create": "Crea", + "cancel": "Annulla" + }, + "form": { + "basics": "Informazioni di base", + "name": "Nome regola", + "namePlaceholder": "es. Brute-force SSH interno", + "description": "Descrizione", + "descriptionPlaceholder": "Perché esiste questa regola e cosa etichetta.", + "tags": "Etichette da applicare", + "noTags": "Nessuna etichetta selezionata.", + "addTag": "Aggiungi etichetta", + "removeTag": "Rimuovi", + "noCatalog": "Nessuna etichetta nel catalogo.", + "createTag": "Crea etichetta", + "newTagName": "Nome nuova etichetta", + "conditions": "Condizioni (devono essere soddisfatte TUTTE)", + "noConditions": "È richiesta almeno una condizione.", + "addCondition": "Aggiungi condizione", + "removeCondition": "Rimuovi condizione", + "valuePlaceholder": "Valore", + "valueListPlaceholder": "Valori separati da virgola", + "incomplete": "Compila il nome della regola, la descrizione, almeno un'etichetta e completa ogni condizione." + }, + "view": { + "description": "Descrizione", + "tags": "Etichette", + "conditions": "Condizioni", + "audit": "Audit", + "createdBy": "Creato da", + "createdDate": "Creato", + "modifiedBy": "Modificato da", + "modifiedDate": "Modificato" + }, + "toast": { + "created": "Regola \"{{name}}\" creata.", + "updated": "Regola \"{{name}}\" aggiornata.", + "deleted": "Regola \"{{name}}\" eliminata.", + "createError": "Impossibile creare la regola.", + "updateError": "Impossibile aggiornare la regola.", + "deleteError": "Impossibile eliminare la regola." + }, + "deleteTitle": "Elimina regola di tagging" + }, + "threatIntel": { + "header": { + "matchedInEnv": "corrispondenze nel tuo ambiente", + "export": "Esporta IOCs", + "exporting": "Esportazione…", + "noInstanceIocs": "Nessun indicatore d'istanza — visualizzazione di dati generici", + "noInstanceIocsHint": "Nessun indicatore osservato nei tuoi avvisi — vengono mostrati i dati generici dei feed." + }, + "overview": { + "title": "Corrispondenze IOC", + "totalIndicators": "indicatori totali", + "families": { + "ip": "IP", + "url": "URL", + "domain": "Dominio", + "signatures": "Firme" + } + }, + "notConfigured": { + "title": "Threat Intelligence non è configurato", + "body": "Contatta il tuo amministratore per connettere un'istanza Cyber Mantra / ThreatWinds a questo ambiente." + }, + "lookup": { + "title": "Ricerca qualsiasi indicatore", + "placeholder": "Incolla un IP, dominio, hash, URL o CVE — controlleremo i feed e il tuo ambiente", + "button": "Ricerca", + "busy": "Ricerca in corso…" + }, + "tabs": { + "iocs": "IOCs", + "actors": "Attori minaccia", + "feeds": "Feed", + "analyst": "Analista IA" + }, + "toolbar": { + "searchPlaceholders": { + "iocs": "Ricerca valore IOC, tag, fonte…", + "actors": "Ricerca attori, alias, tecniche…", + "feeds": "Ricerca feed…" + }, + "last24h": "Ultimi 24 ore", + "filters": "Filtri", + "refresh": "Aggiorna" + }, + "iocs": { + "table": { + "type": "Tipo", + "indicator": "Indicatore", + "reputation": "Reputazione", + "tags": "Tag", + "lastSeen": "Ultimo avvistamento" + }, + "empty": "Nessuna corrispondenza IOC.", + "loadingMore": "Caricamento in corso…", + "loadedProgress": "Caricati {{loaded}} di {{total}}. Scorri per altri.", + "endOfResults": "Fine dei risultati ({{loaded}} di {{total}})." + }, + "drawer": { + "loading": "Caricamento…", + "accuracy": "Accuratezza:", + "actions": { + "block": "Blocca al perimetro", + "viewEvents": "Visualizza eventi corrispondenti", + "externalLookup": "Ricerca esterna", + "trackCampaign": "Traccia campagna", + "viewIocs": "Visualizza IOCs corrispondenti", + "mitre": "MITRE ATT&CK" + }, + "sections": { + "timeline": "Cronologia", + "networkOrigin": "Rete / origine", + "associationsWithCount": "Associazioni ({{count}})", + "geolocationsWithCount": "Geolocazioni ({{count}})", + "about": "Informazioni", + "activity": "Attività" + }, + "fields": { + "firstSeen": "Primo avvistamento", + "lastSeen": "Ultimo avvistamento", + "country": "Paese", + "city": "Città", + "aso": "ASO", + "asn": "ASN", + "reputation": "Reputazione", + "accuracy": "Accuratezza", + "current": "Attuale", + "best": "Migliore", + "worst": "Peggiore" + }, + "aiBrief": "Riassunto IA", + "noDescription": "Nessuna descrizione disponibile per questo indicatore.", + "lastObserved": "Ultimo avvistamento {{when}}." + }, + "actors": { + "empty": "Nessun attore trovato." + }, + "feeds": { + "empty": "Nessun feed configurato.", + "table": { + "name": "Feed", + "type": "Tipo", + "accuracy": "Accuratezza", + "header": "Feed", + "format": "Formato" + }, + "download": "Scarica feed", + "checksum": "Checksum" + }, + "entityTypes": { + "ip": "IP", + "hostname": "Host", + "domain": "Dominio", + "url": "URL", + "hash": "Hash", + "cve": "CVE", + "threat": "Minaccia", + "entity": "Entità" + }, + "reputation": { + "alarming": "Allarmante", + "suspicious": "Sospetto", + "indefinable": "Indefinibile", + "fair": "Equo", + "trustworthy": "Affidabile" + }, + "feedAccuracy": { + "level1": "Livello 1", + "level2": "Livello 2", + "level3": "Livello 3" + }, + "triage": { + "title": "Triage", + "subtitle": "Paste indicators, get verdicts", + "input": "Indicators", + "placeholder": "Paste IPs, domains, URLs or hashes — one per line, or comma separated.\nDefanged values (1.2.3[.]4, hxxp://) are accepted.", + "run": "Triage", + "stop": "Stop", + "reset": "Clear", + "parsed": "{{count}} unique indicators", + "capped": "Capped at {{max}} per run.", + "progress": "{{done}} of {{total}}", + "empty": "Paste indicators above to begin.", + "indicator": "Indicator", + "type": "Type", + "verdict": "Verdict", + "reputation": "Rep", + "accuracy": "Acc", + "tags": "Tags", + "lastSeen": "Last seen", + "exportCsv": "Export CSV", + "exportStix": "Export STIX", + "stixNote": "STIX export includes malicious and suspicious rows only.", + "open": "Open", + "notConfigured": "Threat intelligence is not configured — triage needs an upstream ThreatWinds instance.", + "summary": "Summary", + "v.malicious": "Malicious", + "v.suspicious": "Suspicious", + "v.benign": "Benign", + "v.unknown": "Unknown", + "v.notFound": "Not found", + "v.invalid": "Unrecognised" + }, + "report": { + "title": "Segnala", + "subtitle": "Pubblica un indicatore nel grafo ThreatWinds", + "submit": "Segnala indicatore", + "submitting": "Segnalazione…", + "error": { + "generic": "Impossibile inviare l'indicatore. Riprova." + }, + "value": { + "label": "Indicatore", + "placeholder": "IP, dominio, URL, hash o indirizzo e-mail" + }, + "type": { + "label": "Tipo", + "placeholder": "Deducibile dal valore", + "inferred": "Dedotto: {{type}}", + "inferenceFailed": "Impossibile dedurre un tipo da questo valore. Scegline uno dall'elenco o scrivilo.", + "unknown": "“{{type}}” non è un tipo di entità. Scegline uno dall'elenco." + }, + "tags": { + "label": "Etichette", + "placeholder": "phishing, furto-di-credenziali" + }, + "description": { + "label": "Note" + }, + "reputation": { + "legend": "Reputazione", + "hint": "Lascia vuoto se non hai emesso un verdetto.", + "alarming": "Allarmante", + "worrying": "Preoccupante", + "concerning": "Sospetto", + "indefinable": "Indefinibile", + "adequate": "Adeguato", + "good": "Buono", + "exceptional": "Eccellente" + }, + "associations": { + "legend": "Indicatori correlati", + "add": "Aggiungi indicatore correlato", + "remove": "Rimuovi", + "valuePlaceholder": "Valore correlato", + "typePlaceholder": "Tipo (facoltativo)", + "modeLabel": "Relazione", + "mode": { + "association": "Correlato a", + "aggregation": "Parte di" + }, + "visibilityConflict": "Non condivide nessun gruppo di visibilità con l'indicatore qui sopra. L'intera invio verrebbe rifiutato." + }, + "attributes": { + "legend": "Dettagli", + "hint": "Facoltativo. Qualsiasi campo vuoto non viene inviato.", + "invalidHex": "Sono attesi {{length}} caratteri esadecimali.", + "invalidHexAny": "Solo caratteri esadecimali.", + "invalidNumber": "È atteso un numero." + }, + "correlate": { + "legend": "Correla", + "hint": "Ogni attributo spuntato viene pubblicato come entità propria, collegata a questa.", + "count_one": "Crea {{count}} entità collegata.", + "count_other": "Crea {{count}} entità collegate." + }, + "scan": { + "notice": "Segnalarlo mette anche in coda una scansione dell'obiettivo." + }, + "receipt": { + "title": "Inviato", + "noVerdict": "Nessun verdetto", + "skipped": "Non inviato, non è stato possibile dedurre un tipo", + "pending": "In attesa che l'indicatore compaia nel corpus…", + "live": "Presente nel corpus — visualizza entità", + "processing": "Ancora in elaborazione. Comparirà quando l'ingestione sarà al passo.", + "another": "Segnala un altro" + }, + "visibility": { + "legend": "Visibile a" + }, + "example": "Prova un esempio" + } }, - "console": { - "section": "Console", - "sectionHint": "Esegui comandi su questo host tramite il suo agente (risposta in tempo reale).", - "open": "Apri console", - "close": "Chiudi", - "hint": "Digita un comando e premi Invio per eseguirlo sull'agente.", - "running": "Esecuzione in corso…", - "placeholder": "Digita un comando…", - "offline": "Questo agente sembra offline — potrebbe non rispondere ai comandi.", - "vars": { - "button": "Variabili", - "title": "Variabili dei comandi", - "subtitle": "Richiamale nei comandi come", - "add": "Nuova variabile", - "name": "Nome", - "value": "Valore", - "description": "Descrizione", - "isSecret": "Segreto (cifrato, mascherato nell'output)", - "secret": "segreto", - "secretHint": "Lascia vuoto per mantenere il valore memorizzato.", - "save": "Salva", - "cancel": "Annulla", - "edit": "Modifica", - "delete": "Elimina", - "loading": "Caricamento in corso…", - "empty": "Nessuna variabile.", - "saved": "Variabile salvata", - "deleted": "Variabile eliminata", - "nameRequired": "Il nome è obbligatorio", - "loadError": "Impossibile caricare le variabili", - "saveError": "Impossibile salvare la variabile", - "deleteError": "Impossibile eliminare la variabile", - "insert": "Inserisci", - "valueRequired": "Il valore è obbligatorio" - }, - "disabled": "Agente offline — i comandi sono disabilitati", - "connError": "Errore di connessione", - "cmdError": "Errore del comando", - "shellSelect": "Tipo di shell", - "noRemoteControl": "Questo agente è stato installato con il controllo remoto disattivato. Rifiuta i comandi, e questo si può cambiare solo sulla macchina stessa.", - "noRemoteControlShort": "Controllo remoto disattivato su questo agente", - "password": { - "title": "Autenticazione", - "hint": "Autenticarsi per eseguire comandi su questo agente.", - "tfaPrompt": "Codice: ", - "confirm": "OK", + "playground": { + "titleFilter": "Prova pipeline", + "titleRule": "Prova regola", + "noDataTypes": "A questa pipeline non è ancora assegnato alcun tipo di dato — aggiungine uno per provarla.", + "dataTypeLabel": "Tipo di dato", + "dataTypePlaceholder": "Nessun tipo di dato disponibile", + "dataTypeSingleHint": "Questa pipeline ha un solo tipo di dato — aggiungine altri per poter scegliere.", + "rawLogLabel": "Log grezzo", + "rawLogPlaceholder": "Incolla una riga di log di esempio…", + "rawLogCounter": "{{chars}} caratteri · {{kb}} KB", + "rawLogTooLarge": "Questo log supera il limite di 1 MB — riducilo prima di eseguire il test.", + "run": { + "label": "Esegui", + "running": "Test in corso…", + "waitHint": "Può richiedere fino a 15 secondi mentre la pipeline elabora il log." + }, + "errors": { + "busy": "Il playground sta eseguendo un altro test — riprova a breve.", + "timeout": "Il test è scaduto — di solito significa che il tipo di dato selezionato non corrisponde al formato del log.", + "validation": "La richiesta non è valida — controlla il log grezzo e il contenuto della pipeline.", + "server": "Il playground non è riuscito a completare il test — riprova." + }, + "notices": { + "geo": "Il plugin di geolocalizzazione non è disponibile in questa versione lite del test di filtri e regole.", + "correlation": "Le regole che fanno riferimento a eventi precedenti tramite le clausole afterEvent o correlation richiedono che eventi corrispondenti siano già presenti nel sistema affinché l'allerta in prova venga generata." + }, + "result": { + "label": "Risultato elaborato", + "empty": "Esegui un test per vedere qui l'evento elaborato.", + "loading": "In attesa dell'evento elaborato…", + "tabs": { + "fields": "Campi", + "json": "JSON" + }, + "fieldsCount_one": "{{count}} campo", + "fieldsCount_other": "{{count}} campi", + "copy": "Copia", + "copied": "Copiato", + "elapsed": "Elaborato in {{time}}", + "elapsedHint": "Tempo tra Esegui e il risultato elaborato", + "searchPlaceholder": "Cerca campi…", + "noMatch": "Nessun campo corrisponde alla tua ricerca." + }, + "alerts": { + "label": "Avvisi", + "empty": "Esegui un test per vedere qui gli avvisi generati.", + "none": "Nessun avviso è stato generato.", + "count_one": "{{count}} avviso", + "count_other": "{{count}} avvisi" + }, + "title": "Test pipeline" + }, + "tenants": { + "title": "Tenant", + "new": "Nuovo tenant", + "subtitle": "Ogni cliente su questa istanza, cosa ha e cosa ti lascia vedere.", + "searchPlaceholder": "Cerca per nome o dominio…", + "loading": "Caricamento tenant…", + "loadFailed": "Impossibile caricare i tenant.", + "retry": "Riprova", + "none": "Ancora nessun tenant.", + "noSearchMatch": "Nessun tenant corrisponde alla ricerca.", "cancel": "Annulla", - "authError": "Autenticazione non riuscita", - "authHint": "Autenticarsi per eseguire comandi su questo agente.", - "authOk": "Autenticato." - } - }, - "health": { - "online": "online", - "offline": "offline", - "total": "totale" - } - }, - "adversaries": { - "title": "Vista avversari", - "subtitle": "Ogni IP, host o utente visto attaccare il tuo ambiente, con tecniche e obiettivi.", - "countChip": "{{count}} avversari", - "refresh": "Aggiorna", - "search": "Cerca per IP, host, utente, paese, ASO…", - "empty": "Nessun avversario corrisponde.", - "loadError": "Impossibile caricare gli avversari.", - "retry": "Riprova", - "views": { - "all": "Tutti", - "high": "Severità alta", - "ip": "IP", - "host": "Host", - "user": "Utenti" - }, - "threat": { - "critical": "Critico", - "high": "Alto", - "medium": "Medio", - "low": "Basso" - }, - "kind": { - "ip": "IP", - "host": "Host", - "user": "Utente" - }, - "layout": { - "list": "Elenco", - "cards": "Schede" - }, - "overview": { - "title": "Attività degli avversari · ultime 24 ore", - "high": "severità alta", - "countries": "paesi", - "alerts": "avvisi", - "ago24": "24h fa", - "ago12": "12h fa", - "now": "ora" - }, - "col": { - "adversary": "Avversario", - "threat": "Minaccia", - "alerts": "Avvisi", - "targets": "Obiettivi", - "lastSeen": "Visto l’ultima volta", - "victims": "Vittime" - }, - "card": { - "alerts": "Avvisi", - "techniques": "Tecniche", - "targets": "Obiettivi" - }, - "tabs": { - "profile": "Profilo", - "techniques": "Tecniche", - "targets": "Obiettivi", - "alerts": "Avvisi" - }, - "drawer": { - "activity": "Attività in 24 ore", - "identification": "Identificazione", - "kindLabel": "Tipo", - "identifier": "Identificatore", - "firstSeen": "Visto la prima volta", - "lastSeen": "Visto l’ultima volta", - "geolocation": "Geolocalizzazione", - "country": "Paese", - "city": "Città", - "topTechniques": "Tecniche principali", - "noTechniques": "Nessuna tecnica registrata.", - "targets": "Obiettivi", - "noTargets": "Nessun obiettivo registrato.", - "recentAlerts": "Avvisi recenti", - "noAlerts": "Nessun avviso.", - "echoes": "{{count}} ripetizioni" - }, - "relative": { - "justNow": "proprio ora", - "minutesAgo": "{{count}}m fa", - "hoursAgo": "{{count}}h fa", - "daysAgo": "{{count}}g fa" - }, - "field": { - "ip": "IP", - "host": "Host", - "user": "Utente", - "port": "Porta", - "domain": "Dominio", - "mac": "MAC", - "country": "Paese", - "city": "Città", - "asn": "ASN", - "aso": "ASO" - } - }, - "timeRange": { - "quick": "Intervalli rapidi", - "relative": "Relativo", - "absolute": "Assoluto", - "last": "Ultimi", - "apply": "Applica", - "allTime": "Tutto il tempo", - "from": "Da", - "to": "A", - "now": "adesso", - "units": { - "minutes": "minuti", - "hours": "ore", - "days": "giorni", - "weeks": "settimane", - "months": "mesi" - }, - "presets": { - "15m": "Ultimi 15 minuti", - "1h": "Ultima ora", - "6h": "Ultime 6 ore", - "24h": "Ultime 24 ore", - "7d": "Ultimi 7 giorni", - "30d": "Ultimi 30 giorni" - } - }, - "alerts": { - "title": "Avvisi", - "matching": "{{count}} corrispondenti", - "subtitle": "Dai priorità a ciò che conta.", - "openNow": "aperti in questo momento.", - "view": { - "alerts": "Avvisi", - "overview": "Panoramica" - }, - "toolbar": { - "searchPlaceholder": "Cerca per nome dell'avviso…", - "allSeverities": "Tutte le gravità", - "export": "Esporta CSV", - "refresh": "Aggiorna" - }, - "severity": { - "high": "Alta", - "medium": "Media", - "low": "Bassa" - }, - "status": { - "open": "Aperto", - "in_review": "In revisione", - "completed": "Completato", - "auto": "Revisione automatica" - }, - "statusTabs": { - "all": "Tutti" - }, - "overview": { - "overTime": "Avvisi nel tempo", - "matchingAlerts": "avvisi corrispondenti", - "noData": "Nessun dato.", - "bySeverity": "Per gravità", - "byStatus": "Per stato" - }, - "filters": { - "add": "Aggiungi filtro", - "clearAll": "Cancella tutto", - "filterValues": "Filtra valori…", - "loadingValues": "Caricamento valori…", - "noValues": "Nessun valore trovato.", - "pickValue": "Scegli un valore per aggiungere il filtro.", - "empty": "(vuoto)", - "cancel": "Annulla", - "addBtn": "Aggiungi" - }, - "ops": { - "CONTAIN": "contiene", - "IS": "è", - "IS_NOT": "non è", - "EXIST": "esiste", - "DOES_NOT_EXIST": "non esiste" - }, - "fields": { - "adversary_domain": "Dominio dell'avversario", - "adversary_geolocation_asn": "ASN dell'avversario", - "adversary_geolocation_aso": "ASO dell'avversario", - "adversary_geolocation_country": "Paese dell'avversario", - "adversary_host": "Host dell'avversario", - "adversary_ip": "IP dell'avversario", - "adversary_url": "URL dell'avversario", - "adversary_user": "Utente dell'avversario", - "assignee": "Assegnato a", - "category": "Categoria", - "dataSource": "Sensore", - "dataType": "Tipo di dato", - "description": "Descrizione", - "id": "ID", - "impactScore": "Rischio", - "impact_availability": "Disponibilità", - "impact_confidentiality": "Riservatezza", - "impact_integrity": "Integrità", - "incidentDetail_incidentName": "Nome dell'incidente", - "incidentDetail_incidentId": "Id incidente", - "isIncident": "È un incidente", - "name": "Nome dell'avviso", - "notes": "Note", - "severity": "Gravità", - "status": "Stato", - "tags": "Tag", - "target_domain": "Dominio dell'obiettivo", - "target_geolocation_asn": "ASN dell'obiettivo", - "target_geolocation_aso": "ASO dell'obiettivo", - "target_geolocation_country": "Paese dell'obiettivo", - "target_host": "Host dell'obiettivo", - "target_ip": "IP dell'obiettivo", - "target_url": "URL dell'obiettivo", - "target_user": "Utente dell'obiettivo", - "technique": "Tecnica" - }, - "tagFilter": { - "tags": "Tag", - "tag_one": "{{count}} tag", - "tag_other": "{{count}} tag", - "clearSelection": "Cancella selezione", - "noTags": "Nessun tag" - }, - "bulk": { - "selected": "{{count}} selezionati", - "setStatus": "Imposta stato", - "addTag": "Aggiungi tag", - "noTags": "Nessun tag", - "addToIncident": "Aggiungi a incidente", - "clear": "Cancella" - }, - "tagEditor": { - "tag": "Tag", - "noTagsYet": "Ancora nessun tag", - "createTag": "Crea tag", - "newTagName": "Nome del nuovo tag…", - "createApply": "Crea e applica tag", - "save": "Salva", - "cancel": "Annulla", - "edit": "Modifica tag", - "delete": "Elimina tag", - "systemLocked": "Tag di sistema (bloccato)", - "alreadyExists": "Questo tag esiste già.", - "color": "Colore {{color}}", - "createRule": "Crea una regola di etichettatura con questa etichetta" - }, - "table": { - "actions": "Azioni", - "alert": "Avviso", - "status": "Stato", - "technique": "Tecnica", - "severity": "Gravità", - "risk": "Rischio", - "echoes": "Echi", - "time": "Ora", - "riskHint": "Punteggio di rischio (0–100), colorato in base alla gravità", - "source": "Origine", - "adversary": "Avversario" - }, - "row": { - "createRuleFromAlert": "Crea un'etichetta da questo avviso", - "createIncident": "Crea un incidente da questo avviso", - "viewIncident": "Vedi dettagli dell'incidente", - "assignedTo": "Assegnato a {{user}}", - "echoesTooltip": "{{count}} echi — clicca per espandere", - "echoesEmpty": "Nessun eco registrato" - }, - "echoes": { - "title": "{{count}} echi", - "close": "Chiudi", - "empty": "Nessun eco registrato per questo avviso.", - "loadError": "Impossibile caricare gli echi." - }, - "list": { - "loading": "Caricamento avvisi…", - "loadError": "Impossibile caricare gli avvisi.", - "retry": "Riprova", - "empty": "Nessun avviso corrisponde a questa vista." - }, - "badge": { - "incident": "Incidente", - "aiAssessed": "Valutato dall’IA" - }, - "drawer": { - "setStatus": "Imposta stato", - "completeFalsePositive": "Completa + falso positivo", - "addToIncident": "Aggiungi a incidente", - "partOfIncident": "Parte di un incidente", - "tabs": { - "summary": "Riepilogo", - "parties": "Parti", - "events": "Eventi", - "history": "Cronologia" - }, - "section": { - "description": "Descrizione", - "solution": "Soluzione", - "references": "Riferimenti", - "details": "Dettagli", - "yourNotes": "Le tue note", - "notes": "Note" - }, - "details": { - "severity": "Gravità", - "risk": "Rischio", - "category": "Categoria", - "technique": "Tecnica", - "sensor": "Sensore", - "dataType": "Tipo di dato", - "alertId": "ID avviso", - "statusNote": "Nota di stato", - "assignee": "Assegnatario" - }, - "incidentDetail": { - "incident": "Incidente", - "id": "ID", - "createdBy": "Creato da", - "created": "Creato" - }, - "notesPlaceholder": "Aggiungi note di indagine…", - "saveNotes": "Salva note", - "assignee": "Assegna", - "assign": "Assegna", - "unassign": "Rimuovi assegnazione", - "unassigned": "Non assegnato", - "loadingUsers": "Caricamento utenti…", - "observationLabel": "Osservazione", - "observationPlaceholder": "Aggiungi un'osservazione…", - "cancel": "Annulla", - "continue": "Continua" - }, - "related": { - "sample": "Un campione fino a ~11 eventi che il motore ha memorizzato su questo avviso. Usa «Vedi tutti i log correlati» per l’insieme completo e senza limiti.", - "loadingEchoes": "Caricamento degli eventi dei suoi echi…", - "sampleWithEchoes": "Gli eventi memorizzati su questo avviso e sui suoi {{count}} echi ({{read}} letti). Usa «Vedi tutti i log correlati» per l’insieme completo e senza limiti.", - "empty": "Nessun evento di campione memorizzato su questo avviso. Carica l’insieme correlato completo nell’Esploratore log.", - "viewAll": "Vedi tutti i log correlati" - }, - "party": { - "source": "Origine / obiettivo", - "adversary": "Avversario", - "noData": "Nessun dato.", - "ip": "IP", - "host": "Host", - "user": "Utente", - "domain": "Dominio", - "country": "Paese" - }, - "history": { - "empty": "Nessuna cronologia registrata.", - "by": "da {{user}}", - "actions": { - "UPDATE_STATUS": "Stato aggiornato", - "UPDATE_TAGS": "Tag aggiornati", - "UPDATE_NOTES": "Note aggiornate", - "UPDATE_SOLUTION": "Soluzione aggiornata", - "MARK_AS_INCIDENT": "Contrassegnato come incidente" - }, - "detail": { - "statusTo": "Stato → {{status}}", - "tags": "Tag: {{tags}}", - "aiAdded": "Valutazione IA aggiunta", - "observationAdded": "Osservazione aggiunta", - "notesUpdated": "Note aggiornate" - } - }, - "ai": { - "title": "Valutazione IA del SOC", - "risk": "rischio {{risk}}", - "score": "{{score}}/100", - "generate": "Genera riepilogo IA", - "hint": "SOC-AI analizza questo avviso e aggiunge una valutazione.", - "generating": "Analisi dell'avviso in corso… può richiedere un minuto.", - "ready": "Riepilogo IA pronto", - "failed": "Impossibile generare il riepilogo IA", - "slow": "Il riepilogo IA sta impiegando più tempo del previsto. Comparirà sull'avviso quando sarà pronto." - }, - "incident": { - "titleAdd_one": "Aggiungi {{count}} avviso a un incidente", - "titleAdd_other": "Aggiungi {{count}} avvisi a un incidente", - "new": "Nuovo incidente", - "existing": "Incidente esistente", - "nameLabel": "Nome dell'incidente", - "namePlaceholder": "es. Sospetta intrusione di Scattered Spider", - "descriptionLabel": "Descrizione", - "descriptionPlaceholder": "Riepilogo facoltativo…", - "pickLabel": "Scegli un incidente", - "loading": "Caricamento…", - "selectPlaceholder": "Seleziona un incidente…", - "willLink_one": "{{count}} avviso sarà collegato.", - "willLink_other": "{{count}} avvisi saranno collegati.", - "cancel": "Annulla", - "create": "Crea incidente", - "add": "Aggiungi a incidente" - }, - "toast": { - "statusUpdated": "Stato aggiornato", - "statusFailed": "Impossibile aggiornare lo stato", - "tagsUpdated": "Tag aggiornati", - "tagsFailed": "Impossibile aggiornare i tag", - "tagCreateFailed": "Impossibile creare il tag", - "tagUpdated": "Tag aggiornato", - "tagUpdateFailed": "Impossibile aggiornare il tag", - "tagDeleted": "Tag eliminato", - "tagDeleteFailed": "Impossibile eliminare il tag", - "notesSaved": "Note salvate", - "notesFailed": "Impossibile salvare le note", - "exportFailed": "Impossibile esportare il CSV", - "noRelatedLogs": "Nessun log correlato trovato per questo avviso", - "relatedLogsFailed": "Impossibile caricare i log correlati", - "incidentCreated": "Incidente creato", - "alertsAdded": "Avvisi aggiunti all’incidente", - "incidentFailed": "Impossibile salvare l’incidente", - "assigned": "Alert assegnato", - "unassigned": "Assegnazione dell'alert rimossa", - "assignFailed": "Impossibile aggiornare l'assegnatario", - "newAlertsToast_title": "Nuovi alert", - "newAlertsToast_count_one": "{{count}} nuovo alert", - "newAlertsToast_count_other": "{{count}} nuovi alert", - "newAlertsToast_view": "Visualizza" - } - }, - "incidents": { - "title": "Incidenti", - "subtitle": "Raggruppa, valuta e risolvi gli alert correlati come incidenti.", - "refresh": "Aggiorna", - "count_one": "{{count}} incidente", - "count_other": "{{count}} incidenti", - "openNow": "aperti ora", - "empty": "Nessun incidente corrispondente.", - "loadError": "Impossibile caricare gli incidenti.", - "retry": "Riprova", - "unassigned": "Non assegnato", - "unknownUser": "Sconosciuto", - "status": { - "open": "Aperto", - "in_review": "In revisione", - "completed": "Completato", - "merged": "Unito" - }, - "sev": { - "high": "Alta", - "medium": "Media", - "low": "Bassa", - "unknown": "Non valutata" - }, - "toolbar": { - "search": "Cerca incidenti…", - "create": "Crea incidente", - "allSeverities": "Tutte le gravità", - "export": "Esporta CSV" - }, - "statusTabs": { - "all": "Tutti" - }, - "filters": { - "add": "Aggiungi filtro", - "clearAll": "Cancella tutto", - "filterValues": "Filtra valori…", - "loadingValues": "Caricamento valori…", - "noValues": "Nessun valore trovato.", - "pickValue": "Scegli un valore per aggiungere il filtro.", - "empty": "(vuoto)", - "cancel": "Annulla", - "addBtn": "Aggiungi" - }, - "ops": { - "IS": "è" - }, - "layout": { - "table": "Tabella", - "board": "Bacheca" - }, - "table": { - "name": "Incidente", - "status": "Stato", - "severity": "Severità", - "assignee": "Assegnato", - "alerts": "Alert", - "created": "Creato" - }, - "drawer": { - "created": "Creato {{date}}", - "alertsCount": "{{count}} alert", - "solutionPlaceholder": "Risoluzione / note di rimedio…", - "solutionHint": "Salvato quando l’incidente passa a Completato.", - "tabs": { - "overview": "Panoramica", - "alerts": "Alert", - "notes": "Note", - "history": "Cronologia" - }, - "section": { - "description": "Descrizione", - "solution": "Soluzione", - "details": "Dettagli" - }, - "details": { - "id": "ID", - "status": "Stato", - "severity": "Severità", - "assignee": "Assegnato", - "created": "Creato", - "alerts": "Alert collegati" - } - }, - "alerts": { - "empty": "Nessun alert collegato a questo incidente.", - "remove": "Scollega alert", - "removeConfirm": "Scollegare “{{name}}” da questo incidente?", - "removed": "Alert scollegato", - "removeError": "Impossibile scollegare l’alert", - "loadingAlert": "Caricamento avviso…", - "alertGone": "Questo avviso non è più nell'archivio — la conservazione potrebbe averlo rimosso.", - "alertFailed": "Impossibile caricare l'avviso.", - "openInAlerts": "Apri in Avvisi" - }, - "notes": { - "empty": "Ancora nessuna nota.", - "add": "Aggiungi nota", - "addError": "Impossibile aggiungere la nota", - "placeholder": "Scrivi una nota…" - }, - "history": { - "empty": "Ancora nessuna cronologia." - }, - "toast": { - "statusChanged": "Stato incidente aggiornato", - "statusError": "Impossibile cambiare lo stato", - "exportFailed": "Impossibile esportare il CSV" - }, - "assign": { - "assign": "Assegna", - "search": "Cerca utenti…", - "unassign": "Rimuovi assegnazione", - "noUsers": "Nessun utente", - "assigned": "Assegnato a {{user}}", - "unassigned": "Incidente non assegnato", - "error": "Impossibile cambiare l’assegnatario", - "custom": "Assegna personalizzato", - "customPlaceholder": "Inserisci un login…" - }, - "action": { - "INCIDENT_CREATED": "Incidente creato", - "INCIDENT_ALERT_ADD": "Avvisi aggiunti", - "INCIDENT_ALERT_STATUS_CHANGED": "Stato degli avvisi cambiato", - "INCIDENT_STATUS_CHANGE": "Stato cambiato", - "INCIDENT_NOTE_ADD": "Nota aggiunta", - "INCIDENT_NOTE_CHANGE": "Nota modificata", - "INCIDENT_ASSIGNED": "Assegnazione cambiata" - }, - "create": { - "title": "Crea incidente", - "stepIndicator": "Passaggio {{current}} di {{total}}", - "selectedCount": "{{count}} avvisi selezionati", - "submit": "Crea", - "success": "Incidente creato", - "error": "Impossibile creare l'incidente", - "details": { - "nameLabel": "Nome", - "namePlaceholder": "Titolo breve e descrittivo", - "descriptionLabel": "Descrizione", - "descriptionPlaceholder": "Contesto, ambito, note iniziali…" - } - } - }, - "alertingRules": { - "title": "Regole di allerta", - "subtitle": "Regole di correlazione che trasformano gli eventi in allarmi. Attiva, regola o crea le tue.", - "new": "Nuova regola", - "refresh": "Aggiorna", - "empty": "Nessuna regola corrispondente.", - "loadError": "Impossibile caricare le regole.", - "retry": "Riprova", - "deleteConfirm": "Eliminare la regola “{{name}}”?", - "adversary": { - "origin": "Origine", - "target": "Destinazione" - }, - "state": { - "active": "Attiva", - "inactive": "Inattiva" - }, - "owner": { - "system": "Sistema", - "custom": "Personalizzata" - }, - "toolbar": { - "search": "Cerca regole…", - "allCategories": "Tutte le categorie", - "allAdversaries": "Tutti gli avversari", - "allStates": "Tutti gli stati", - "allOwners": "Tutte le origini", - "allDataTypes": "Tutti i tipi" - }, - "table": { - "name": "Regola", - "category": "Categoria", - "technique": "Tecnica", - "adversary": "Avversario", - "impact": "Impatto", - "active": "Attiva", - "dataTypes": "Tipi di dato", - "selectAll": "Seleziona tutto", - "selectRow": "Seleziona {{name}}" - }, - "export": { - "all": "Esporta tutto", - "selected": "Esporta ({{count}})", - "error": "Impossibile esportare le regole" - }, - "view": { - "description": "Descrizione", - "details": "Dettagli", - "impact": "Impatto (C·I·D)", - "dataTypes": "Tipi di dato", - "updated": "Aggiornata", - "relPath": "Percorso", - "definition": "Condizione (CEL)", - "correlationSteps": "Passi di correlazione", - "correlation": "Correlazione", - "groupBy": "Raggruppa per", - "deduplicateBy": "Deduplica per", - "references": "Riferimenti" - }, - "editor": { - "createTitle": "Nuova regola", - "edit": "Modifica", - "delete": "Elimina", - "export": "Esporta", - "cancel": "Annulla", - "save": "Salva", - "metadata": "Metadati", - "name": "Nome", - "confidentiality": "Riservatezza", - "integrity": "Integrità", - "availability": "Disponibilità", - "dataTypes": "Tipi di dato", - "dataTypesHint": "separati da virgola", - "activeOnSave": "Attiva", - "definitionSection": "Definizione", - "where": "Condizione (CEL)", - "whereHint": "Espressione CEL valutata per evento", - "correlationSteps": "Passi di correlazione", - "correlationStepsHint": "array JSON", - "jsonArray": "array JSON", - "nameRequired": "Il nome è obbligatorio", - "definitionRequired": "La condizione è obbligatoria", - "invalidJson": "Un campo della definizione ha JSON non valido", - "addStep": "Aggiungi passo di correlazione", - "step": "Passo {{n}}", - "removeStep": "Rimuovi passo", - "indexPattern": "Pattern indice", - "within": "Finestra", - "count": "Conteggio", - "conditions": "Condizioni", - "field": "Campo", - "value": "Valore", - "addCondition": "Aggiungi condizione", - "orGroup": "Gruppo Or {{n}}", - "addOr": "Aggiungi gruppo Or", - "removeOr": "Rimuovi", - "fieldsHint": "nomi dei campi", - "referencesHint": "URL", - "visual": "Visuale", - "code": "Codice", - "dataTypesPick": "Seleziona…", - "dataTypesSearch": "Cerca tipi di dato…", - "dataTypesNone": "Nessun tipo di dato", - "visualTab": "Visuale", - "codeTab": "Codice", - "yamlError": "Impossibile applicare lo YAML: {{error}}", - "test": "Test" - }, - "toast": { - "activated": "Regola attivata", - "deactivated": "Regola disattivata", - "toggleError": "Impossibile cambiare lo stato della regola", - "deleted": "Regola eliminata", - "deleteError": "Impossibile eliminare la regola", - "created": "Regola creata", - "saved": "Regola salvata", - "saveError": "Impossibile salvare la regola" - }, - "operator": { - "filter_term": "uguale (term)", - "must_not_term": "diverso (term)", - "filter_match": "corrisponde (testo)", - "must_not_match": "non corrisponde (testo)" - }, - "where": { - "matchPrefix": "Soddisfa", - "all": "tutte", - "any": "almeno una", - "matchSuffix": "di queste condizioni:", - "negate": "Nega", - "listHint": "separati da virgole", - "advanced": "Questa condizione usa CEL avanzato — modificala in Codice o ricostruiscila visivamente.", - "and": "E", - "or": "O" - }, - "celOp": { - "exists": "esiste", - "equals": "uguale a", - "equalsIgnoreCase": "uguale (senza maiusc.)", - "contains": "contiene", - "oneOf": "è uno di", - "containsAll": "contiene tutti", - "startsWith": "inizia con", - "endsWith": "finisce con", - "regexMatch": "regex", - "lessThan": "<", - "lessOrEqual": "≤", - "greaterThan": ">", - "greaterOrEqual": "≥", - "inCIDR": "in CIDR", - "isHour": "l’ora è", - "isMinute": "il minuto è", - "isDayOfWeek": "il giorno è", - "isWeekend": "è weekend", - "isWorkDay": "è giorno feriale", - "isBetweenTime": "ora tra" - }, - "import": { - "button": "Importa", - "error": "Importazione non riuscita", - "resultTitle": "Risultati dell'importazione", - "approved": "Approvate", - "rejected": "Rifiutate", - "done": "Fatto" - }, - "test": "Test" - }, - "regexPatterns": { - "title": "Espressioni regolari", - "subtitle": "Espressioni regolari riutilizzabili referenziate dai filtri di parsing.", - "new": "Nuovo pattern", - "search": "Cerca pattern…", - "refresh": "Aggiorna", - "view": "Visualizza", - "system": "Sistema", - "user": "Personalizzato", - "loading": "Caricamento pattern…", - "loadError": "Impossibile caricare i pattern.", - "retry": "Riprova", - "empty": "Nessun pattern corrisponde a questa vista.", - "tabs": { - "all": "Tutti", - "system": "Sistema", - "user": "Personalizzati" - }, - "cols": { - "pattern": "Pattern", - "definition": "Definizione", - "type": "Tipo" - }, - "editor": { - "titleNew": "Nuovo pattern", - "patternId": "ID pattern", - "patternIdHint": "Nome univoco referenziato dai filtri.", - "description": "Descrizione", - "descriptionPlaceholder": "Cosa riconosce questo pattern (opzionale)", - "definition": "Definizione (regex)", - "definitionHint": "Un'espressione regolare. Può referenziare altri pattern.", - "readOnly": "Pattern di sistema — sola lettura.", - "save": "Salva", - "saving": "Salvataggio…", - "delete": "Elimina", - "confirmDelete": "Conferma eliminazione", - "cancel": "Annulla" - }, - "toast": { - "saved": "Pattern salvato", - "saveError": "Salvataggio del pattern non riuscito", - "deleted": "Pattern eliminato", - "deleteError": "Eliminazione del pattern non riuscita", - "patternIdRequired": "L'ID pattern è obbligatorio", - "definitionRequired": "La definizione è obbligatoria" - } - }, - "parsingFilters": { - "title": "Pipeline", - "subtitle": "Pipeline YAML applicate ai log durante l'analisi in fase di ingestione.", - "new": "Nuova pipeline", - "search": "Cerca pipeline…", - "refresh": "Aggiorna", - "view": "Vedi", - "system": "Sistema", - "user": "Personalizzato", - "loading": "Caricamento pipeline…", - "loadError": "Impossibile caricare le pipeline.", - "retry": "Riprova", - "empty": "Nessuna pipeline corrisponde a questa vista.", - "tabs": { - "all": "Tutti", - "active": "Attivi", - "inactive": "Inattivi", - "system": "Sistema", - "user": "Personalizzati" - }, - "cols": { - "filter": "Pipeline", - "type": "Tipo", - "active": "Attivo", - "dataTypes": "Tipi di dati", - "order": "Ordine", - "moveUp": "Sposta su", - "moveDown": "Sposta giù", - "actions": "Azioni" - }, - "editor": { - "titleNew": "Nuova pipeline", - "titleEdit": "Modifica pipeline", - "titleSystem": "Pipeline (sistema)", - "name": "Nome", - "namePlaceholder": "La mia pipeline personalizzata", - "nameHint": "Verrà salvato come {{file}}", - "namePending": "Scegli un nome — diventerà il nome del file.", - "content": "Contenuto (YAML pipeline)", - "contentHint": "Una definizione YAML pipeline: valida.", - "readOnly": "Pipeline di sistema — in sola lettura. Puoi solo abilitarla o disabilitarla.", - "save": "Salva", - "saving": "Salvataggio…", - "delete": "Elimina", - "confirmDelete": "Conferma eliminazione", - "cancel": "Annulla", - "test": "Test" - }, - "toast": { - "saved": "Pipeline salvata", - "saveError": "Salvataggio della pipeline non riuscito", - "deleted": "Pipeline eliminata", - "deleteError": "Eliminazione della pipeline non riuscita", - "activateError": "Modifica dello stato della pipeline non riuscita", - "nameRequired": "Il nome è obbligatorio", - "contentRequired": "Il contenuto è obbligatorio", - "orderError": "Impossibile modificare l'ordine della pipeline" - }, - "visual": { - "visualTab": "Visuale", - "codeTab": "Codice", - "codeOnly": "Passa al Codice — questo contenuto non può essere mostrato visivamente.", - "cantParse": "Impossibile aprire l'editor visuale: {{error}}", - "dataTypes": "Tipi di dati", - "steps": "Passaggi", - "noSteps": "Ancora nessun passaggio.", - "addStep": "Aggiungi passaggio:", - "removeStep": "Rimuovi passaggio", - "moveUp": "Su", - "moveDown": "Giù", - "whereHint": "condizione opzionale (CEL)", - "addValue": "Aggiungi valore", - "addPattern": "Aggiungi pattern", - "rawHint": "Questo processore si modifica come YAML grezzo.", - "rawNotMap": "Deve essere un insieme di campi chiave: valore.", - "dataTypesPick": "Scegli tipi di dati", - "dataTypesSearch": "Cerca tipi di dati…", - "dataTypesNone": "Nessun tipo di dato", - "dataTypesAdd": "Aggiungi \"{{value}}\"", - "insertPattern": "Inserisci pattern regex", - "patternSearch": "Cerca pattern…", - "patternNone": "Nessun pattern", - "newPattern": "Nuovo pattern…", - "createInsert": "Crea e inserisci", - "patternCreated": "Pattern \"{{name}}\" creato", - "patternCreateError": "Creazione del pattern non riuscita", - "patternIdInvalid": "L'ID del pattern deve iniziare con una lettera o _ e usare solo lettere, cifre o _", - "patternDefRequired": "La definizione è obbligatoria", - "parameters": "Parametri", - "paramsKey": "Chiave", - "paramsValue": "Valore", - "entry": "Vocetta {{n}}", - "order": "ordine {{n}}", - "orderLabel": "Ordine", - "removeEntry": "Rimuovi vocetta", - "addEntry": "Aggiungi vocetta di pipeline", - "collapse": "Comprimi", - "expand": "Espandi", - "splitHint": "Vacío equivale a un espacio por defecto — en el YAML siempre aparece como fieldSplit: \" \"." - }, - "allDataTypes": "Tutti i tipi di dati", - "testPipeline": "Test pipeline" - }, - "soar": { - "title": "SOAR", - "subtitle": "Flussi di risposta automatica: le condizioni corrispondono a un alert, i comandi vengono eseguiti sull'agente.", - "comingSoon": "Prossimamente", - "console": { - "loading": "Caricamento agenti…", - "loadError": "Impossibile caricare gli agenti.", - "pickAgent": "Seleziona un agente", - "pickAgentHint": "Scegli un agente dall'elenco per aprire la sua console interattiva.", - "lockedAgent": "Controllo remoto disattivato" - }, - "search": "Cerca flussi…", - "refresh": "Aggiorna", - "new": "Nuovo flusso", - "view": "Vedi", - "system": "Sistema", - "loading": "Caricamento flussi…", - "loadError": "Impossibile caricare i flussi.", - "retry": "Riprova", - "empty": "Nessun flusso corrisponde a questa vista.", - "templates": { - "title": "Nuovo flusso", - "subtitle": "Scegli un modello di azione o parti da zero.", - "loading": "Caricamento modelli…", - "loadError": "Impossibile caricare i modelli.", - "empty": "Nessun modello disponibile.", - "cancel": "Annulla", - "scratch": "Parti da zero" - }, - "tabs": { - "flows": "Flussi", - "executions": "Cronologia esecuzioni", - "all": "Tutti", - "active": "Attivi", - "inactive": "Inattivi", - "system": "Sistema", - "user": "Personalizzati" - }, - "cols": { - "flow": "Flusso", - "platform": "Piattaforma", - "conditions": "Condizioni", - "commands": "Comandi", - "active": "Attivo", - "lastRun": "Ultima esecuzione", - "failedRuns_one": "{{count}} esecuzione fallita", - "failedRuns_other": "{{count}} esecuzioni fallite" - }, - "operator": { - "IS": "è", - "IS_NOT": "non è", - "CONTAINS": "contiene", - "NOT_CONTAINS": "non contiene", - "EXISTS": "esiste", - "NOT_EXISTS": "non esiste", - "START_WITH": "inizia con", - "NOT_START_WITH": "non inizia con", - "ENDS_WITH": "termina con", - "NOT_ENDS_WITH": "non termina con", - "IS_ONE_OF": "è uno di", - "IS_NOT_ONE_OF": "non è uno di" - }, - "toast": { - "created": "Flusso creato", - "saved": "Flusso salvato", - "saveError": "Salvataggio del flusso non riuscito", - "deleted": "Flusso eliminato", - "deleteError": "Eliminazione del flusso non riuscita", - "activateError": "Modifica dello stato del flusso non riuscita" - }, - "editor": { - "createTitle": "Nuovo flusso", - "visualTab": "Visuale", - "codeTab": "Codice", - "name": "Nome", - "description": "Descrizione", - "conditions": "Condizioni", - "conditionsHint": "Il flusso viene eseguito quando un alert soddisfa TUTTE queste condizioni.", - "field": "campo", - "value": "valore", - "valueList": "valori separati da virgola", - "addCondition": "Aggiungi condizione", - "commands": "Comandi", - "commandsHint": "Eseguiti in ordine sull'agente. Usa $(field.path) per i valori dell'alert e $[variables.NAME] per le variabili salvate.", - "addCommand": "Aggiungi comando", - "templatesButton": "Comandi comuni", - "templates": { - "isolate": "Isola dalla rete", - "shutdown": "Spegni macchina", - "killProcess": "Termina processo", - "logout": "Disconnetti utente", - "disableUser": "Disabilita utente", - "blockIp": "Blocca IP", - "restart": "Riavvia la macchina", - "uninstall": "Disinstalla applicazione" - }, - "connector": { - "always": "sempre", - "success": "se riuscito", - "failure": "se fallito" - }, - "agentPlatform": "Piattaforma dell'agente", - "shell": "Shell", - "shellAuto": "auto", - "whereToRun": "Dove eseguire", - "run": { - "all": "Tutti gli agenti", - "specific": "Un agente", - "except": "Tutti tranne", - "allHint": "Viene eseguito su ogni agente che corrisponde a questa piattaforma." - }, - "selectAgentPlaceholder": "Seleziona un agente…", - "excludedAgentsHint": "digita un hostname e premi Invio", - "save": "Salva", - "delete": "Elimina", - "confirmDelete": "Conferma eliminazione", - "cancel": "Annulla", - "yamlError": "Impossibile applicare lo YAML: {{error}}", - "nameRequired": "Il nome è obbligatorio", - "conditionsRequired": "È richiesta almeno una condizione con un campo", - "commandsRequired": "È richiesto almeno un comando", - "httpUrlInvalid": "Il nodo HTTP \"{{id}}\" ha un URL non valido — deve essere un URL http(s) valido.", - "httpBodyInvalid": "Il corpo del nodo HTTP \"{{id}}\" non è JSON valido: {{error}}", - "incidentNameRequired": "Il nodo incidente \"{{id}}\" richiede un nome.", - "mailToRequired": "Il nodo e-mail \"{{id}}\" richiede almeno un destinatario.", - "mailAddressInvalid": "Il nodo e-mail \"{{id}}\" contiene un indirizzo {{field}} non valido: {{address}}.", - "mailSubjectRequired": "Il nodo e-mail \"{{id}}\" richiede un oggetto.", - "identityModalTitle": "Dettagli del flusso", - "platformRequired": "La piattaforma dell'agente è obbligatoria", - "nameLabel": "Nome", - "namePlaceholder": "Nome del flusso", - "descriptionLabel": "Descrizione", - "descriptionHint": "Cosa fa questo flusso? (opzionale)", - "when": "Quando", - "whenTitle": "Un alert soddisfa tutte queste condizioni", - "on": "Su", - "onTitle": "L'agente corrispondente", - "thenRun": "Allora esegui", - "thenTitle": "Questi comandi, in ordine", - "selectField": "Scegli un campo…", - "selectPlatform": "Scegli una piattaforma…", - "searchAgents": "Cerca agenti…", - "noAgents": "Nessun agente", - "insertInto": "Inserisci nel comando {{n}}:", - "insertField": "Campo dell'alert", - "variables": "Variabili", - "canvas": { - "node": "Nodo", - "deleteNode": "Elimina nodo", - "id": "ID", - "kind": "Tipo", - "executor": "Esecutore", - "commandLabel": "Comando", - "paramsJson": "Parametri (JSON)", - "dragToResize": "Trascina per ridimensionare", - "templatesLabel": "Modelli", - "templatesNeedPlatform": "Seleziona prima la piattaforma di destinazione", - "handlesHint": "Trascina dalla maniglia verde (in basso a sinistra) per on_success e da quella rossa (in basso a destra) per on_error. Più connessioni = parallelo. Più connessioni verso lo stesso nodo = AND-join.", - "invalidJson": "JSON non valido", - "hidePalette": "Nascondi tavolozza", - "hideInspector": "Nascondi ispettore", - "paletteLabel": "Tavolozza", - "nodeShort": "Nodo", - "showPanel": "Mostra {{name}}", - "platform": "Piattaforma", - "shell": "Shell", - "any": "qualsiasi", - "auto": "auto", - "runOn": "Esegui su", - "runAutoTitle": "Esegue sull'host che ha generato l'allerta", - "runSpecificTitle": "Fissa a un host (o un modello come $(alert.foo))", - "runExceptTitle": "Esegue sull'host che ha generato l'allerta, escludendo quelli nella lista", - "runAutoLabel": "sorgente allerta", - "runSpecificLabel": "un host", - "runExceptLabel": "tutti tranne", - "runAutoHint": "Esegue su $(alert.dataSource) — l'host che ha generato l'allerta.", - "pickHost": "scegli un host…", - "orTemplateHint": "O digita un modello — $(alert.field) viene risolto ad ogni esecuzione.", - "addExclusion": "aggiungi esclusione", - "searchAgents": "cerca agenti…", - "noAgents": "nessun agente", - "insertField": "Inserisci campo", - "alert": "Allerta", - "wholeOutput": "output completo (modifica il percorso)", - "noAncestorsHint": "Nessun antenato di arricchimento — aggiungi un nodo di arricchimento a monte per esporre qui il suo output.", - "inserts": "inserisce", - "conditionalHint": "Tutte le condizioni devono corrispondere. Corrispondenza → ramo di successo (verde); mancata → ramo di errore (rosso).", - "http": { - "url": "URL", - "urlInvalid": "URL http(s) non valido.", - "method": "Metodo", - "body": "Corpo (JSON)", - "bodyInvalid": "JSON non valido", - "headers": "Intestazioni HTTP", - "params": "Parametri di query", - "key": "Chiave", - "value": "Valore", - "addHeader": "Aggiungi intestazione", - "addParam": "Aggiungi parametro" + "saving": "Salvataggio…", + "chips": { + "total": "tenant", + "active": "attivi", + "readable": "accessibili" }, - "incident": { - "name": "Nome dell'incidente", - "namePlaceholder": "Es. Accesso sospetto su $(alert.dataSource)", - "description": "Descrizione", - "descriptionPlaceholder": "Contesto facoltativo per i risponditori. I template come $(alert.name) vengono interpolati." - }, - "llm": { - "prompt": "Prompt", - "hint": "Al modello è imposto di rispondere sempre con un unico oggetto JSON con la proprietà \"result\"; il backend garantisce questa forma anche se il modello devia. I nodi figli lo consultano tramite $({{nodeId}}.result) o campi specifici." - }, - "mail": { - "to": "A (separati da virgola)", - "cc": "CC (separati da virgola, opzionale)", - "addressInvalid": "Indirizzo e-mail non valido: {{address}}", - "subject": "Oggetto", - "subjectPlaceholder": "Es. Allarme su $(alert.dataSource)", - "body": "Corpo", - "bodyPlaceholder": "Contenuto del messaggio. I template come $(alert.name) vengono interpolati." - }, - "notify": { - "level": "Level", - "message": "Message", - "messagePlaceholder": "Notification text. Templates like $(alert.name) are interpolated." + "status": { + "ACTIVE": "Attivo", + "SUSPENDED": "Sospeso", + "TERMINATED": "Terminato" + }, + "support": { + "NONE": "Nessun accesso", + "READ": "Accesso in lettura", + "FULL": "Accesso completo", + "hint": "Lo concede il tenant, non tu. Solo il suo amministratore può cambiarlo." + }, + "card": { + "edit": "Modifica", + "activate": "Attiva", + "deactivate": "Disattiva", + "deletePermanent": "Elimina definitivamente", + "noAccess": "Questo tenant non ti ha dato accesso.", + "loadingStats": "Lettura…", + "enter": "Entra" + }, + "stats": { + "users": "Utenti", + "datasources": "Sorgenti", + "openAlerts": "Avvisi aperti", + "ai": "IA oggi", + "noLimit": "nessun limite" + }, + "fields": { + "name": "Nome", + "domain": "Dominio", + "domainHint": "Da dove si raggiunge questo tenant. Ogni richiesta a questo host entra nei suoi dati.", + "adminEmail": "E-mail dell'amministratore", + "adminEmailHint": "Riceve un invito per impostare la propria password.", + "status": "Stato", + "suspendedWarning": "Un tenant sospeso non può accedere. I suoi dati vengono conservati.", + "aiLimit": "Limite di richieste IA", + "aiLimitHint": "Un limite operativo, al giorno. Senza limite, consumano sulla licenza dell'istanza.", + "aiLimitToggle": "Limita questo tenant" + }, + "create": { + "title": "Nuovo tenant", + "subtitle": "Crea il tenant e invita il suo primo amministratore.", + "submit": "Crea tenant" + }, + "edit": { + "title": "Modifica tenant", + "subtitle": "L'accesso di supporto non è qui: può concederlo solo il tenant.", + "submit": "Salva modifiche" + }, + "terminate": { + "title": "Disattivare questo tenant?", + "body": "Nessuno in {{name}} potrà più accedere. I dati restano, quindi è reversibile, ma il cliente resta fuori da subito.", + "confirmLabel": "Scrivi {{name}} per confermare", + "submit": "Disattiva" + }, + "reactivate": { + "title": "Attivare questo tenant?", + "body": "{{name}} potrà accedere di nuovo. I dati conservati vengono ripristinati così come sono.", + "submit": "Attiva" + }, + "deletePermanent": { + "title": "Eliminare questo tenant per sempre?", + "body": "Ogni traccia di {{name}} — utenti, sorgenti dati, dashboard, avvisi, integrazioni — sarà cancellata. Non si può annullare.", + "confirmLabel": "Scrivi {{name}} per confermare", + "submit": "Elimina per sempre" + }, + "toast": { + "created": "Tenant creato", + "updated": "Tenant aggiornato", + "terminated": "Tenant terminato", + "reactivated": "Tenant riattivato", + "permanentlyDeleted": "Tenant eliminato definitivamente", + "domainInUse": "Questo dominio è già in uso", + "noPermission": "Non hai il permesso di farlo", + "notFound": "Tenant non trovato", + "invalidRequest": "Richiesta non valida", + "operationFailed": "Operazione fallita" + }, + "switcher": { + "aria": "Switch tenant", + "self": "Default tenant", + "create": "Create tenant" } - } - }, - "executions": { - "search": "Cerca per ID alert…", - "all": "Tutte", - "loading": "Caricamento esecuzioni…", - "loadError": "Impossibile caricare le esecuzioni.", - "retry": "Riprova", - "empty": "Ancora nessuna esecuzione.", - "cols": { - "status": "Stato", - "flow": "Flusso", - "command": "Comando / Acción", - "agent": "Agente", - "date": "Data", - "retries": "Tentativi", - "node": "Nodo" - }, - "filters": { - "source": "Origine", - "allSources": "Tutte le origini" - }, - "manual": "Console interattiva" - }, - "executionStatus": { - "WAITING": "In attesa", - "PENDING": "In coda", - "EXECUTING": "In esecuzione", - "EXECUTED": "Eseguito", - "FAILED": "Fallito", - "DEAD": "Non raggiungibile" - }, - "executionOrigin": { - "FLOW": "Flusso", - "MANUAL": "Manuale" - }, - "nonExecutionCause": { - "AGENT_OFFLINE": "Agente offline", - "AGENT_NOT_FOUND": "Agente non trovato", - "UNKNOWN": "Sconosciuto" - }, - "kpi": { - "flows": "Flussi totali", - "active": "Attivi", - "runs24h": "Esecuzioni (24h)", - "failed24h": "Fallite (24h)" - }, - "neverRun": "mai", - "create": { - "title": "Nuovo flusso", - "modeManual": "Crea manualmente", - "modeAi": "Con IA", - "aiLocked": "Abilita SOC-AI e configuralo per usarlo.", - "name": "Nome del flusso", - "namePlaceholder": "es. Blocca IP in caso di fallimenti ripetuti", - "aiDescriptionLabel": "Cosa deve fare questo flusso?", - "aiDescriptionPlaceholder": "es. In caso di alert critico, cerca l'IP di origine nell'intelligence sulle minacce e bloccalo sul firewall", - "aiCreate": "Crea con IA", - "manualContinue": "Continua" - } - }, - "compliance": { - "title": "Compliance", - "subtitle": "Valuta la tua postura rispetto ai framework di sicurezza — vedi quali controlli sono soddisfatti e quali no.", - "comingSoon": "Prossimamente.", - "tabs": { - "frameworks": "Framework", - "schedule": "Pianificazione", - "controls": "Controlli" - }, - "search": "Cerca framework…", - "refresh": "Refresh", - "loading": "Caricamento framework…", - "loadError": "Could not load reports", - "retry": "Riprova", - "empty": "Nessun framework corrisponde.", - "notEvaluated": "Non valutato", - "controlsCount": "{{n}} controlli", - "enabledLabel": "Attivo", - "runReport": "Esegui report", - "backToFrameworks": "Torna ai framework", - "statusAuto": "Auto (valutato)", - "overrideError": "Impossibile aggiornare lo stato", - "noteError": "Impossibile salvare la nota", - "notes": { - "title": "Note", - "placeholder": "Aggiungi una nota…", - "save": "Salva", - "cancel": "Annulla" }, - "reasonModal": { - "title": "Motivazione richiesta", - "description": "Indica il motivo del cambio di stato. Verrà registrato.", - "label": "Motivazione", - "placeholder": "Spiega perché stai cambiando lo stato di questo controllo…", - "confirm": "Conferma cambio", - "cancel": "Annulla" - }, - "coverageLabel": "Copertura", - "activityLabel": "Attività", - "evidenceLabel": "Evidenza", - "seeMore": "Mostra di più", - "seeLess": "Mostra meno", - "evaluating": "Valutazione del framework…", - "complianceScore": "Punteggio di conformità", - "generatedAt": "Generato {{date}}", - "reportError": "Impossibile generare il report.", - "coverage": "{{n}} regole", - "activity": "{{n}} avvisi", - "status": { - "COMPLIANT": "Conforme", - "NON_COMPLIANT": "Non conforme", - "AT_RISK": "A rischio", - "NOT_COVERED": "Non coperto", - "OUT_OF_SCOPE": "Fuori ambito", - "PENDING": "In sospeso", - "label": "Stato", - "NOT_EVALUATED": "Not evaluated" - }, - "toast": { - "toggleError": "Impossibile cambiare lo stato del framework", - "reportGenerated": "Report generato", - "reportError": "Impossibile generare il report" - }, - "schedule": { - "new": "Nuova pianificazione", - "loading": "Caricamento pianificazioni…", - "loadError": "Impossibile caricare le pianificazioni.", - "empty": "Ancora nessuna pianificazione.", - "edit": "Modifica", - "delete": "Elimina", - "newTitle": "Nuova pianificazione", - "editTitle": "Modifica pianificazione", - "framework": "Framework", - "cadenceLabel": "Cadenza", - "cronHint": "Cron a 5 campi (min ora giorno mese giornoSettimana).", - "recipientsHint": "Email separate da virgola. Lascia vuoto per salvare solo lo snapshot.", - "save": "Salva", - "cancel": "Annulla", - "frameworkRequired": "Il framework è obbligatorio", - "cronRequired": "La pianificazione (cron) è obbligatoria", - "cadence": { - "daily": "Giornaliera", - "weekly": "Settimanale", - "monthly": "Mensile", - "custom": "Personalizzata" - }, - "toast": { - "saved": "Pianificazione salvata", - "saveError": "Impossibile salvare la pianificazione", - "deleted": "Pianificazione eliminata", - "deleteError": "Impossibile eliminare la pianificazione" - }, - "to": "To", - "cc": "Cc", - "toRequired": "At least one recipient is required", - "windowDays": "Reporting window (days)", - "windowDaysShort": "over {{days}}d", - "windowDaysHint": "How far back the report counts. Independent of how often it runs." - }, - "frameworks": { - "new": "Nuovo framework", - "edit": "Modifica", - "createTitle": "Nuovo framework", - "visualTab": "Visuale", - "codeTab": "Codice", - "key": "Chiave", - "name": "Nome", - "description": "Descrizione", - "source": "Fonte", - "sections": "Sezioni", - "sectionKey": "chiave sezione", - "sectionName": "Nome della sezione", - "requirements": "Requisiti", - "reqId": "id req.", - "reqName": "Nome del requisito", - "addSection": "Aggiungi sezione", - "addRequirement": "Aggiungi requisito", - "satisfiedBy": "soddisfatto dai controlli", - "searchControls": "Cerca controlli…", - "noControls": "Nessun controllo", - "save": "Salva", - "delete": "Elimina", - "confirmDelete": "Conferma eliminazione", - "cancel": "Annulla", - "yamlError": "Impossibile applicare lo YAML: {{error}}", - "keyRequired": "La chiave è obbligatoria", - "nameRequired": "Il nome è obbligatorio", - "toast": { - "created": "Framework creato", - "saved": "Framework salvato", - "saveError": "Impossibile salvare il framework", - "deleted": "Framework eliminato", - "deleteError": "Impossibile eliminare il framework" - }, - "createControl": "Crea nuovo controllo…", - "createNamed": "Crea controllo \"{{name}}\"…" - }, - "controls": { - "search": "Cerca controlli…", - "allFamilies": "Tutte le famiglie", - "new": "Nuovo controllo", - "loading": "Caricamento controlli…", - "loadError": "Impossibile caricare i controlli.", - "empty": "Nessun controllo corrisponde.", - "showingOf": "Visualizzati {{shown}} di {{total}}", - "id": "ID", - "name": "Nome", - "family": "Famiglia", - "familyName": "Famiglia", - "scope": "Ambito", - "source": "Origine", - "notInLibrary": "Controllo non trovato in libreria", - "scopeOpt": { - "data": "Dati", - "governance": "Governance" - }, - "strategy": "Strategia", - "statement": "Enunciato", - "remediation": "Rimedio", - "checks": "Verifiche", - "checksHint": "Ogni verifica esegue una query SQL su OpenSearch e applica una regola per decidere superato/fallito.", - "checkKey": "chiave", - "checkName": "Nome della verifica", - "rule": { - "MIN_HITS_REQUIRED": "Risultati minimi richiesti", - "THRESHOLD_MAX": "Soglia massima" - }, - "ruleNone": "Nessuna regola", - "ruleValue": "valore", - "addCheck": "Aggiungi verifica", - "createTitle": "Nuovo controllo", - "visualTab": "Visuale", - "codeTab": "Codice", - "save": "Salva", - "delete": "Elimina", - "confirmDelete": "Conferma eliminazione", - "cancel": "Annulla", - "yamlError": "Impossibile applicare lo YAML: {{error}}", - "idRequired": "L'ID è obbligatorio", - "nameRequired": "Il nome è obbligatorio", - "anyDataType": "Any data type", - "addFilter": "Add filter", - "filterField": "log.eventCode", - "filterValue": "value", - "filterValues": "a, b, c", - "toast": { - "created": "Controllo creato", - "saved": "Controllo salvato", - "saveError": "Impossibile salvare il controllo", - "deleted": "Controllo eliminato", - "deleteError": "Impossibile eliminare il controllo" - } - }, - "doc": { - "title": "Report di conformità", - "print": "Stampa / PDF", - "controlsEvaluated": "{{n}} controlli valutati", - "executiveSummary": "Sintesi esecutiva", - "bySection": "Risultati per sezione", - "footer": "{{framework}} — Report di conformità generato {{date}} · {{brand}}", - "download": "Scarica PDF", - "downloadError": "Impossibile scaricare il PDF", - "error": "Impossibile generare il PDF", - "building": "Generazione del documento…" - }, - "locked": { - "badge": "Enterprise", - "upgrade": "Passa a Enterprise", - "upsell": "Questo framework/controllo richiede l'edizione Enterprise." - }, - "run": "Run evaluation", - "runError": "Evaluation failed", - "noReportYet": "This framework has not been evaluated yet.", - "window": "window {{from}} → {{to}}", - "scoredOver": "{{compliant}} of {{evaluated}} requirements met · {{total}} in the framework", - "editStale": "Recorded when the engine said {{was}}; it now says {{now}}", - "checkResults": "Check results", - "verdict": "Recorded verdict", - "engineSaid": "engine said", - "hits": "hits", - "noDataFor": "no {{dataType}} data in the window", - "setStatus": "Set status", - "outcome": { - "PASSED": "Passed", - "FAILED": "Failed", - "NOT_APPLICABLE": "No data", - "ERROR": "Error" - }, - "system": "Di sistema", - "addNote": "Aggiungi nota", - "noteModal": { - "title": "Nota", - "description": "Registrata nel report. Non cambia lo stato del controllo.", - "placeholder": "Rimedio in corso — ticket OPS-4412." - }, - "history": { - "title": "Score nel tempo", - "score": "Score di conformità", - "coverage": "Valutati", - "error": "Impossibile caricare lo storico" - } - }, - "socAi": { - "title": "Configurazione SOC-AI", - "subtitle": "Configura l'agente AI che esegue il triage degli alert e alimenta l'assistente operativo.", - "section": { - "connection": "Modello e connessione", - "auth": "Autenticazione", - "behavior": "Comportamento del triage degli alert", - "advanced": "Avanzate" - }, - "usage": { - "title": "Utilizzo", - "chat": "Completamenti chat (oggi)", - "unavailable": "L'utilizzo non è ancora disponibile.", - "resetsIn": "Si azzera tra {{time}}" - }, - "provider": { - "label": "Provider", - "hint": "Seleziona il formato di trasmissione. Qualsiasi opzione diversa da Anthropic usa l'API compatibile con OpenAI." - }, - "model": { - "label": "Modello", - "hint": "Identificatore del modello esposto dal provider.", - "customOption": "Modello personalizzato…", - "customPlaceholder": "Inserisci un ID modello" - }, - "url": { - "label": "URL API", - "hint": "Lascia vuoto per usare l'endpoint predefinito del provider." - }, - "apiKey": { - "label": "Chiave API", - "hint": "Credenziale inviata al provider.", - "setHint": "Una chiave è memorizzata. Lascia vuoto per mantenerla." - }, - "authType": { - "label": "Tipo di autenticazione", - "hint": "Come vengono inviate le credenziali al tuo gateway.", - "options": { - "apiKey": "API Key", - "bearer": "Bearer", - "customHeaders": "Header personalizzati", - "none": "Nessuna" - } - }, - "authHeaderName": { - "label": "Nome header di autenticazione", - "hint": "Header che trasporta la chiave (es. api-key per Azure)." - }, - "authToken": { - "label": "Token Bearer", - "hint": "Credenziale inviata al provider.", - "setHint": "È memorizzato un token. Lascia vuoto per mantenerlo." - }, - "customHeaders": { - "label": "Header personalizzati", - "hint": "Header aggiuntivi inviati a ogni richiesta. I valori sono cifrati; \"*****\" mantiene quello memorizzato.", - "keyPlaceholder": "Nome header", - "valuePlaceholder": "Valore", - "addRow": "Aggiungi header", - "remove": "Rimuovi header" - }, - "maxTokens": { - "label": "Token massimi", - "hint": "Numero massimo di token per risposta dell'LLM." - }, - "maxToolIterations": { - "label": "Iterazioni massime degli strumenti", - "hint": "Limite al ciclo dell'agente piano -> strumento -> osservazione." - }, - "autoAnalyze": { - "label": "Analisi automatica degli alert", - "hint": "Esegui il triage degli alert in arrivo in tempo reale." - }, - "allowIncidents": { - "label": "Consenti la gestione degli incident", - "hint": "L'agente di triage può creare o aggiornare incident quando ritiene che un alert lo giustifichi." - }, - "changeAlertStatus": { - "label": "Modifica stato degli alert", - "hint": "Consenti all'agente di impostare lo stato di un alert durante il triage." - }, - "automaticIncidentCreation": { - "label": "Crea incident", - "hint": "Consenti all'agente di aprire incident dagli alert sottoposti a triage." - }, - "allowedWriteTools": { - "label": "Strumenti di scrittura consentiti", - "hint": "Un nome di strumento MCP per riga che l'agente di triage può usare (es. alerts.update_status). Le note sono sempre consentite." - }, - "save": "Salva configurazione", - "saving": "Verifica e salvataggio in corso...", - "saved": "Configurazione SOC-AI salvata", - "saveError": "Impossibile salvare la configurazione", - "loadError": "Impossibile caricare la configurazione", - "modelRequired": "Il modello è obbligatorio", - "applyTags": { - "label": "Applica etichette", - "hint": "Consenti all'agente di etichettare gli alert durante il triage." - }, - "note": { - "azure": "Incolla l'endpoint completo del tuo deployment Azure come URL; il modello è il nome del tuo deployment. L'autenticazione usa l'header api-key.", - "ollama": "Punta l'URL al tuo host Ollama. Non è necessaria alcuna chiave API per un'istanza locale.", - "custom": "Qualsiasi endpoint compatibile con OpenAI. Imposta l'URL, l'autenticazione e gli eventuali header aggiuntivi richiesti dal tuo gateway.", - "threatwinds": "Usa automaticamente la tua licenza UTMStack — non serve una API key. Fatturato tramite il tuo abbonamento ThreatWinds." - }, - "chat": { - "title": "Assistente SOC", - "dashboardCreateTitle": "Creazione dashboard", - "empty": "Chiedi qualsiasi cosa sui tuoi alert, sulle rilevazioni o sulla console — posso investigare e agire sul SIEM.", - "tryPrefix": "Prova", - "suggestion": "quanti alert aperti, raggruppati per avversario?", - "placeholder": "Fai una domanda…", - "ask": "Chiedi", - "send": "Invia", - "collapse": "Comprimi", - "expand": "Espandi", - "clear": "Cancella conversazione", - "close": "Chiudi", - "copy": "Copia", - "copied": "Copiato", - "errorGeneric": "Si è verificato un errore.", - "errorUnreachable": "Impossibile raggiungere l'assistente.", - "compacting": "Compattazione del contesto…", - "dashboardEditTitle": "Editor dashboard", - "editingDashboard": "Modifica di: {{name}}", - "soarEditTitle": "Editor di flussi SOAR", - "soarCreateTitle": "Crea un flusso SOAR", - "editingFlow": "Modifica del flusso: {{name}}" - }, - "focus": { - "alert": "Avviso", - "incident": "Incidente", - "remove": "Smetti di condividere con l'assistente" - }, - "inheritance": { - "inherited": "Segue l'impostazione predefinita dell'istanza. Salvando, questo tenant avrà la propria.", - "own": "Questo tenant ha una configurazione propria.", - "revert": "Torna a quella dell'istanza", - "reverting": "Ripristino…", - "reverted": "Ora segue l'impostazione dell'istanza" - }, - "allowance": { - "title": "Consumo IA oggi", - "ofLimit": "di {{limit}} richieste", - "denied": "richieste — l'IA non è disponibile per questo tenant", - "hint": "Deciso da chi gestisce l'istanza. Si azzera a mezzanotte UTC." - } - }, - "taggingRules": { - "title": "Regole di etichettatura", - "subtitle": "Etichetta automaticamente gli alert che soddisfano le condizioni.", - "new": "Nuova regola", - "refresh": "Aggiorna", - "empty": "Nessuna regola di etichettatura.", - "loadError": "Impossibile caricare le regole di etichettatura.", - "retry": "Riprova", - "deleteConfirm": "Eliminare la regola \"{{name}}\"? Gli alert futuri che soddisfano le sue condizioni non verranno più etichettati.", - "toolbar": { - "search": "Cerca per nome regola…", - "allTags": "Tutte le etichette" - }, - "table": { - "rule": "Regola", - "tags": "Etichette", - "conditions": "Condizioni", - "modifiedBy": "Modificato da", - "modifiedDate": "Modificato" - }, - "drawer": { - "createTitle": "Nuova regola di etichettatura", - "edit": "Modifica", - "delete": "Elimina", - "save": "Salva", - "create": "Crea", - "cancel": "Annulla" - }, - "form": { - "basics": "Informazioni di base", - "name": "Nome regola", - "namePlaceholder": "es. Brute-force SSH interno", - "description": "Descrizione", - "descriptionPlaceholder": "Perché esiste questa regola e cosa etichetta.", - "tags": "Etichette da applicare", - "noTags": "Nessuna etichetta selezionata.", - "addTag": "Aggiungi etichetta", - "removeTag": "Rimuovi", - "noCatalog": "Nessuna etichetta nel catalogo.", - "createTag": "Crea etichetta", - "newTagName": "Nome nuova etichetta", - "conditions": "Condizioni (devono essere soddisfatte TUTTE)", - "noConditions": "È richiesta almeno una condizione.", - "addCondition": "Aggiungi condizione", - "removeCondition": "Rimuovi condizione", - "valuePlaceholder": "Valore", - "valueListPlaceholder": "Valori separati da virgola", - "incomplete": "Compila il nome della regola, la descrizione, almeno un'etichetta e completa ogni condizione." - }, - "view": { - "description": "Descrizione", - "tags": "Etichette", - "conditions": "Condizioni", - "audit": "Audit", - "createdBy": "Creato da", - "createdDate": "Creato", - "modifiedBy": "Modificato da", - "modifiedDate": "Modificato" - }, - "toast": { - "created": "Regola \"{{name}}\" creata.", - "updated": "Regola \"{{name}}\" aggiornata.", - "deleted": "Regola \"{{name}}\" eliminata.", - "createError": "Impossibile creare la regola.", - "updateError": "Impossibile aggiornare la regola.", - "deleteError": "Impossibile eliminare la regola." - }, - "deleteTitle": "Elimina regola di tagging" - }, - "threatIntel": { - "header": { - "matchedInEnv": "corrispondenze nel tuo ambiente", - "export": "Esporta IOCs", - "exporting": "Esportazione…", - "noInstanceIocs": "Nessun indicatore d'istanza — visualizzazione di dati generici", - "noInstanceIocsHint": "Nessun indicatore osservato nei tuoi avvisi — vengono mostrati i dati generici dei feed." - }, - "overview": { - "title": "Corrispondenze IOC", - "totalIndicators": "indicatori totali", - "families": { - "ip": "IP", - "url": "URL", - "domain": "Dominio", - "signatures": "Firme" - } - }, - "notConfigured": { - "title": "Threat Intelligence non è configurato", - "body": "Contatta il tuo amministratore per connettere un'istanza Cyber Mantra / ThreatWinds a questo ambiente." - }, - "lookup": { - "title": "Ricerca qualsiasi indicatore", - "placeholder": "Incolla un IP, dominio, hash, URL o CVE — controlleremo i feed e il tuo ambiente", - "button": "Ricerca", - "busy": "Ricerca in corso…" - }, - "tabs": { - "iocs": "IOCs", - "actors": "Attori minaccia", - "feeds": "Feed", - "analyst": "Analista IA" - }, - "toolbar": { - "searchPlaceholders": { - "iocs": "Ricerca valore IOC, tag, fonte…", - "actors": "Ricerca attori, alias, tecniche…", - "feeds": "Ricerca feed…" - }, - "last24h": "Ultimi 24 ore", - "filters": "Filtri", - "refresh": "Aggiorna" - }, - "iocs": { - "table": { - "type": "Tipo", - "indicator": "Indicatore", - "reputation": "Reputazione", - "tags": "Tag", - "lastSeen": "Ultimo avvistamento" - }, - "empty": "Nessuna corrispondenza IOC.", - "loadingMore": "Caricamento in corso…", - "loadedProgress": "Caricati {{loaded}} di {{total}}. Scorri per altri.", - "endOfResults": "Fine dei risultati ({{loaded}} di {{total}})." - }, - "drawer": { - "loading": "Caricamento…", - "accuracy": "Accuratezza:", - "actions": { - "block": "Blocca al perimetro", - "viewEvents": "Visualizza eventi corrispondenti", - "externalLookup": "Ricerca esterna", - "trackCampaign": "Traccia campagna", - "viewIocs": "Visualizza IOCs corrispondenti", - "mitre": "MITRE ATT&CK" - }, - "sections": { - "timeline": "Cronologia", - "networkOrigin": "Rete / origine", - "associationsWithCount": "Associazioni ({{count}})", - "geolocationsWithCount": "Geolocazioni ({{count}})", - "about": "Informazioni", - "activity": "Attività" - }, - "fields": { - "firstSeen": "Primo avvistamento", - "lastSeen": "Ultimo avvistamento", - "country": "Paese", - "city": "Città", - "aso": "ASO", - "asn": "ASN", - "reputation": "Reputazione", - "accuracy": "Accuratezza", - "current": "Attuale", - "best": "Migliore", - "worst": "Peggiore" - }, - "aiBrief": "Riassunto IA", - "noDescription": "Nessuna descrizione disponibile per questo indicatore.", - "lastObserved": "Ultimo avvistamento {{when}}." - }, - "actors": { - "empty": "Nessun attore trovato." - }, - "feeds": { - "empty": "Nessun feed configurato.", - "table": { - "name": "Feed", - "type": "Tipo", - "accuracy": "Accuratezza", - "header": "Feed", - "format": "Formato" - }, - "download": "Scarica feed", - "checksum": "Checksum" - }, - "entityTypes": { - "ip": "IP", - "hostname": "Host", - "domain": "Dominio", - "url": "URL", - "hash": "Hash", - "cve": "CVE", - "threat": "Minaccia", - "entity": "Entità" - }, - "reputation": { - "alarming": "Allarmante", - "suspicious": "Sospetto", - "indefinable": "Indefinibile", - "fair": "Equo", - "trustworthy": "Affidabile" - }, - "feedAccuracy": { - "level1": "Livello 1", - "level2": "Livello 2", - "level3": "Livello 3" - }, - "triage": { - "title": "Triage", - "subtitle": "Paste indicators, get verdicts", - "input": "Indicators", - "placeholder": "Paste IPs, domains, URLs or hashes — one per line, or comma separated.\nDefanged values (1.2.3[.]4, hxxp://) are accepted.", - "run": "Triage", - "stop": "Stop", - "reset": "Clear", - "parsed": "{{count}} unique indicators", - "capped": "Capped at {{max}} per run.", - "progress": "{{done}} of {{total}}", - "empty": "Paste indicators above to begin.", - "indicator": "Indicator", - "type": "Type", - "verdict": "Verdict", - "reputation": "Rep", - "accuracy": "Acc", - "tags": "Tags", - "lastSeen": "Last seen", - "exportCsv": "Export CSV", - "exportStix": "Export STIX", - "stixNote": "STIX export includes malicious and suspicious rows only.", - "open": "Open", - "notConfigured": "Threat intelligence is not configured — triage needs an upstream ThreatWinds instance.", - "summary": "Summary", - "v.malicious": "Malicious", - "v.suspicious": "Suspicious", - "v.benign": "Benign", - "v.unknown": "Unknown", - "v.notFound": "Not found", - "v.invalid": "Unrecognised" - }, - "report": { - "title": "Segnala", - "subtitle": "Pubblica un indicatore nel grafo ThreatWinds", - "submit": "Segnala indicatore", - "submitting": "Segnalazione…", - "error": { - "generic": "Impossibile inviare l'indicatore. Riprova." - }, - "value": { - "label": "Indicatore", - "placeholder": "IP, dominio, URL, hash o indirizzo e-mail" - }, - "type": { - "label": "Tipo", - "placeholder": "Deducibile dal valore", - "inferred": "Dedotto: {{type}}", - "inferenceFailed": "Impossibile dedurre un tipo da questo valore. Scegline uno dall'elenco o scrivilo.", - "unknown": "“{{type}}” non è un tipo di entità. Scegline uno dall'elenco." - }, - "tags": { - "label": "Etichette", - "placeholder": "phishing, furto-di-credenziali" - }, - "description": { - "label": "Note" - }, - "reputation": { - "legend": "Reputazione", - "hint": "Lascia vuoto se non hai emesso un verdetto.", - "alarming": "Allarmante", - "worrying": "Preoccupante", - "concerning": "Sospetto", - "indefinable": "Indefinibile", - "adequate": "Adeguato", - "good": "Buono", - "exceptional": "Eccellente" - }, - "associations": { - "legend": "Indicatori correlati", - "add": "Aggiungi indicatore correlato", - "remove": "Rimuovi", - "valuePlaceholder": "Valore correlato", - "typePlaceholder": "Tipo (facoltativo)", - "modeLabel": "Relazione", - "mode": { - "association": "Correlato a", - "aggregation": "Parte di" - }, - "visibilityConflict": "Non condivide nessun gruppo di visibilità con l'indicatore qui sopra. L'intera invio verrebbe rifiutato." - }, - "attributes": { - "legend": "Dettagli", - "hint": "Facoltativo. Qualsiasi campo vuoto non viene inviato.", - "invalidHex": "Sono attesi {{length}} caratteri esadecimali.", - "invalidHexAny": "Solo caratteri esadecimali.", - "invalidNumber": "È atteso un numero." - }, - "correlate": { - "legend": "Correla", - "hint": "Ogni attributo spuntato viene pubblicato come entità propria, collegata a questa.", - "count_one": "Crea {{count}} entità collegata.", - "count_other": "Crea {{count}} entità collegate." - }, - "scan": { - "notice": "Segnalarlo mette anche in coda una scansione dell'obiettivo." - }, - "receipt": { - "title": "Inviato", - "noVerdict": "Nessun verdetto", - "skipped": "Non inviato, non è stato possibile dedurre un tipo", - "pending": "In attesa che l'indicatore compaia nel corpus…", - "live": "Presente nel corpus — visualizza entità", - "processing": "Ancora in elaborazione. Comparirà quando l'ingestione sarà al passo.", - "another": "Segnala un altro" - }, - "visibility": { - "legend": "Visibile a" - }, - "example": "Prova un esempio" - } - }, - "playground": { - "titleFilter": "Prova pipeline", - "titleRule": "Prova regola", - "noDataTypes": "A questa pipeline non è ancora assegnato alcun tipo di dato — aggiungine uno per provarla.", - "dataTypeLabel": "Tipo di dato", - "dataTypePlaceholder": "Nessun tipo di dato disponibile", - "dataTypeSingleHint": "Questa pipeline ha un solo tipo di dato — aggiungine altri per poter scegliere.", - "rawLogLabel": "Log grezzo", - "rawLogPlaceholder": "Incolla una riga di log di esempio…", - "rawLogCounter": "{{chars}} caratteri · {{kb}} KB", - "rawLogTooLarge": "Questo log supera il limite di 1 MB — riducilo prima di eseguire il test.", - "run": { - "label": "Esegui", - "running": "Test in corso…", - "waitHint": "Può richiedere fino a 15 secondi mentre la pipeline elabora il log." - }, - "errors": { - "busy": "Il playground sta eseguendo un altro test — riprova a breve.", - "timeout": "Il test è scaduto — di solito significa che il tipo di dato selezionato non corrisponde al formato del log.", - "validation": "La richiesta non è valida — controlla il log grezzo e il contenuto della pipeline.", - "server": "Il playground non è riuscito a completare il test — riprova." - }, - "notices": { - "geo": "Il plugin di geolocalizzazione non è disponibile in questa versione lite del test di filtri e regole.", - "correlation": "Le regole che fanno riferimento a eventi precedenti tramite le clausole afterEvent o correlation richiedono che eventi corrispondenti siano già presenti nel sistema affinché l'allerta in prova venga generata." - }, - "result": { - "label": "Risultato elaborato", - "empty": "Esegui un test per vedere qui l'evento elaborato.", - "loading": "In attesa dell'evento elaborato…", - "tabs": { - "fields": "Campi", - "json": "JSON" - }, - "fieldsCount_one": "{{count}} campo", - "fieldsCount_other": "{{count}} campi", - "copy": "Copia", - "copied": "Copiato", - "elapsed": "Elaborato in {{time}}", - "elapsedHint": "Tempo tra Esegui e il risultato elaborato", - "searchPlaceholder": "Cerca campi…", - "noMatch": "Nessun campo corrisponde alla tua ricerca." - }, - "alerts": { - "label": "Avvisi", - "empty": "Esegui un test per vedere qui gli avvisi generati.", - "none": "Nessun avviso è stato generato.", - "count_one": "{{count}} avviso", - "count_other": "{{count}} avvisi" - }, - "title": "Test pipeline" - }, - "tenants": { - "title": "Tenant", - "new": "Nuovo tenant", - "subtitle": "Ogni cliente su questa istanza, cosa ha e cosa ti lascia vedere.", - "searchPlaceholder": "Cerca per nome o dominio…", - "loading": "Caricamento tenant…", - "loadFailed": "Impossibile caricare i tenant.", - "retry": "Riprova", - "none": "Ancora nessun tenant.", - "noSearchMatch": "Nessun tenant corrisponde alla ricerca.", - "cancel": "Annulla", - "saving": "Salvataggio…", - "chips": { - "total": "tenant", - "active": "attivi", - "readable": "accessibili" - }, - "status": { - "ACTIVE": "Attivo", - "SUSPENDED": "Sospeso", - "TERMINATED": "Terminato" - }, - "support": { - "NONE": "Nessun accesso", - "READ": "Accesso in lettura", - "FULL": "Accesso completo", - "hint": "Lo concede il tenant, non tu. Solo il suo amministratore può cambiarlo." - }, - "card": { - "edit": "Modifica", - "activate": "Attiva", - "deactivate": "Disattiva", - "deletePermanent": "Elimina definitivamente", - "noAccess": "Questo tenant non ti ha dato accesso.", - "loadingStats": "Lettura…", - "enter": "Entra" - }, - "stats": { - "users": "Utenti", - "datasources": "Sorgenti", - "openAlerts": "Avvisi aperti", - "ai": "IA oggi", - "noLimit": "nessun limite" - }, - "fields": { - "name": "Nome", - "domain": "Dominio", - "domainHint": "Da dove si raggiunge questo tenant. Ogni richiesta a questo host entra nei suoi dati.", - "adminEmail": "E-mail dell'amministratore", - "adminEmailHint": "Riceve un invito per impostare la propria password.", - "status": "Stato", - "suspendedWarning": "Un tenant sospeso non può accedere. I suoi dati vengono conservati.", - "aiLimit": "Limite di richieste IA", - "aiLimitHint": "Un limite operativo, al giorno. Senza limite, consumano sulla licenza dell'istanza.", - "aiLimitToggle": "Limita questo tenant" - }, - "create": { - "title": "Nuovo tenant", - "subtitle": "Crea il tenant e invita il suo primo amministratore.", - "submit": "Crea tenant" - }, - "edit": { - "title": "Modifica tenant", - "subtitle": "L'accesso di supporto non è qui: può concederlo solo il tenant.", - "submit": "Salva modifiche" - }, - "terminate": { - "title": "Disattivare questo tenant?", - "body": "Nessuno in {{name}} potrà più accedere. I dati restano, quindi è reversibile, ma il cliente resta fuori da subito.", - "confirmLabel": "Scrivi {{name}} per confermare", - "submit": "Disattiva" - }, - "reactivate": { - "title": "Attivare questo tenant?", - "body": "{{name}} potrà accedere di nuovo. I dati conservati vengono ripristinati così come sono.", - "submit": "Attiva" - }, - "deletePermanent": { - "title": "Eliminare questo tenant per sempre?", - "body": "Ogni traccia di {{name}} — utenti, sorgenti dati, dashboard, avvisi, integrazioni — sarà cancellata. Non si può annullare.", - "confirmLabel": "Scrivi {{name}} per confermare", - "submit": "Elimina per sempre" - }, - "toast": { - "created": "Tenant creato", - "updated": "Tenant aggiornato", - "terminated": "Tenant terminato", - "reactivated": "Tenant riattivato", - "permanentlyDeleted": "Tenant eliminato definitivamente", - "domainInUse": "Questo dominio è già in uso", - "noPermission": "Non hai il permesso di farlo", - "notFound": "Tenant non trovato", - "invalidRequest": "Richiesta non valida", - "operationFailed": "Operazione fallita" - }, - "switcher": { - "aria": "Switch tenant", - "self": "Default tenant", - "create": "Create tenant" - } - }, - "supportAccess": { - "title": "Accesso di supporto", - "intro": "Chi gestisce questa istanza non può guardare dentro i tuoi dati se non glielo permetti. Qui non è concesso nulla per impostazione predefinita, e puoi revocarlo quando vuoi.", - "loading": "Caricamento…", - "loadFailed": "Impossibile leggere l'impostazione attuale.", - "retry": "Riprova", - "currentBadge": "attuale", - "save": "Salva", - "saving": "Salvataggio…", - "levels": { - "NONE": { - "name": "Nessun accesso", - "desc": "L'operatore vede che il tuo tenant esiste e nulla più. Ogni richiesta verso i tuoi dati viene rifiutata." - }, - "READ": { - "name": "Sola lettura", - "desc": "L'operatore può vedere avvisi, log e configurazione per aiutarti. Non può cambiare nulla: ogni scrittura viene rifiutata, qualunque sia il suo ruolo." - }, - "FULL": { - "name": "Accesso completo", - "desc": "L'operatore può agire nel tuo tenant come amministratore: configurazione, utenti e flussi di risposta." - } - }, - "fullWarning": "L'accesso completo gli permette di cambiare cose a tuo nome. Concedilo finché ti serve assistenza diretta, poi torna indietro.", - "revokeNote": "Tutto ciò che l'operatore fa qui resta nel tuo registro di audit.", - "toast": { - "granted": "Accesso di supporto aggiornato", - "revoked": "Accesso di supporto revocato", - "forbidden": "Solo un amministratore di questo tenant può cambiarlo", - "invalid": "Richiesta non valida", - "failed": "Impossibile salvare la modifica" - } - }, - "supportSession": { - "inside": "Stai lavorando dentro {{name}}", - "readOnly": "sola lettura — le scritture vengono rifiutate", - "full": "accesso completo — le modifiche qui sono reali", - "leave": "Esci" - }, - "platformBroadcast": { - "button": "Applica a tutti i tenant", - "action": { - "create": "Trasmetti creazione {{resource}}", - "update": "Trasmetti aggiornamento {{resource}}", - "delete": "Trasmetti eliminazione {{resource}}", - "toggle": "Trasmetti commutazione {{resource}}", - "enable": "Trasmetti abilitazione {{resource}}", - "activate": "Trasmetti attivazione {{resource}}", - "test": "Trasmetti test {{resource}}", - "upload": "Trasmetti risorsa {{resource}}" - }, - "resource": { - "pipeline": "pipeline", - "correlationRule": "regola di correlazione", - "soarFlow": "flusso SOAR", - "framework": "framework", - "control": "controllo", - "smtp": "SMTP", - "idp": "provider di identità", - "branding": "branding" - }, - "warning": { - "title": "Questa azione verrà eseguita su ogni tenant selezionato.", - "body": "Gli errori per tenant vengono segnalati dopo l'esecuzione e non vengono annullati." - }, - "allTenants": "Applica a tutti i tenant", - "excludesDefault": "Il tenant della piattaforma è escluso da questa azione.", - "searchPlaceholder": "Cerca tenant…", - "loading": "Caricamento tenant…", - "empty": "Nessun tenant corrispondente.", - "targetCount": "Sarà applicato a {{count}} tenant.", - "platformTenant": "piattaforma", - "confirm": "Applica a {{count}} tenant", - "result": { - "succeeded": "Riusciti", - "noneSucceeded": "Nessun tenant riuscito.", - "failed": "Falliti", - "noneFailed": "Nessun errore." - } - }, - "tiAnalyst": { - "console": { - "subtitle": "Area analista", - "model": "Modello", - "resizeResults": "Ridimensiona il pannello dei risultati", - "resizeHint": "Trascina per ridimensionare · doppio clic per reimpostare" - }, - "conv": { - "title": "Conversazioni", - "allConversations": "Tutte le conversazioni", - "empty": "Nessuna conversazione al momento.", - "new": "Nuova conversazione", - "newTitle": "Titolo della conversazione", - "selectPrompt": "Seleziona una conversazione o avviane una.", - "running": "in corso", - "delete": "Elimina {{title}}", - "unread_one": "{{count}} messaggio non letto", - "unread_other": "{{count}} messaggi non letti", - "transcript": "Trascrizione della conversazione" - }, - "agent": { - "placeholder": "Indaga su un indicatore…", - "ask": "Chiedi all'agente analista", - "intro": "Chiedi qualsiasi indicatore. L'agente interroga direttamente ThreatWinds e mostra il suo lavoro.", - "send": "Invia", - "stop": "Ferma", - "thinking": "pensiero…", - "suggestionInvestigate": "Indaga su 8.8.8.8 e dimmi se è malevolo", - "suggestionInfrastructure": "Che infrastruttura è collegata a google.com?", - "suggestionCounts": "Mostrami quante entità esistono per tipo" + "supportAccess": { + "title": "Accesso di supporto", + "intro": "Chi gestisce questa istanza non può guardare dentro i tuoi dati se non glielo permetti. Qui non è concesso nulla per impostazione predefinita, e puoi revocarlo quando vuoi.", + "loading": "Caricamento…", + "loadFailed": "Impossibile leggere l'impostazione attuale.", + "retry": "Riprova", + "currentBadge": "attuale", + "save": "Salva", + "saving": "Salvataggio…", + "levels": { + "NONE": { + "name": "Nessun accesso", + "desc": "L'operatore vede che il tuo tenant esiste e nulla più. Ogni richiesta verso i tuoi dati viene rifiutata." + }, + "READ": { + "name": "Sola lettura", + "desc": "L'operatore può vedere avvisi, log e configurazione per aiutarti. Non può cambiare nulla: ogni scrittura viene rifiutata, qualunque sia il suo ruolo." + }, + "FULL": { + "name": "Accesso completo", + "desc": "L'operatore può agire nel tuo tenant come amministratore: configurazione, utenti e flussi di risposta." + } + }, + "fullWarning": "L'accesso completo gli permette di cambiare cose a tuo nome. Concedilo finché ti serve assistenza diretta, poi torna indietro.", + "revokeNote": "Tutto ciò che l'operatore fa qui resta nel tuo registro di audit.", + "toast": { + "granted": "Accesso di supporto aggiornato", + "revoked": "Accesso di supporto revocato", + "forbidden": "Solo un amministratore di questo tenant può cambiarlo", + "invalid": "Richiesta non valida", + "failed": "Impossibile salvare la modifica" + } }, - "canvas": { - "title": "Risultati", - "empty": "I risultati di questa conversazione appaiono qui.", - "tile": "Ordina", - "closeAll": "Chiudi tutto", - "pinOut": "Apri {{title}} come pannello", - "loading": "caricamento…", - "failed": "impossibile caricare", - "noRelations": "nessuna entità correlata", - "noGeo": "nessuna geolocalizzazione registrata", - "noResults": "nessuna corrispondenza", - "matches": "{{total}} corrispondenze", - "panelName": "{{title}} — {{kind}}", - "movePanel": "Sposta {{title}}", - "resizePanel": "Ridimensiona {{title}}", - "closePanel": "Chiudi {{title}}", - "collapse": "Comprimi {{title}}", - "expand": "Espandi {{title}}", - "kind": { - "entity": "dossier", - "graph": "relazioni", - "geo": "geolocalizzazione", - "search": "ricerca" - } + "supportSession": { + "inside": "Stai lavorando dentro {{name}}", + "readOnly": "sola lettura — le scritture vengono rifiutate", + "full": "accesso completo — le modifiche qui sono reali", + "leave": "Esci" + }, + "platformBroadcast": { + "button": "Applica a tutti i tenant", + "action": { + "create": "Trasmetti creazione {{resource}}", + "update": "Trasmetti aggiornamento {{resource}}", + "delete": "Trasmetti eliminazione {{resource}}", + "toggle": "Trasmetti commutazione {{resource}}", + "enable": "Trasmetti abilitazione {{resource}}", + "activate": "Trasmetti attivazione {{resource}}", + "test": "Trasmetti test {{resource}}", + "upload": "Trasmetti risorsa {{resource}}" + }, + "resource": { + "pipeline": "pipeline", + "correlationRule": "regola di correlazione", + "soarFlow": "flusso SOAR", + "framework": "framework", + "control": "controllo", + "smtp": "SMTP", + "idp": "provider di identità", + "branding": "branding" + }, + "warning": { + "title": "Questa azione verrà eseguita su ogni tenant selezionato.", + "body": "Gli errori per tenant vengono segnalati dopo l'esecuzione e non vengono annullati." + }, + "allTenants": "Applica a tutti i tenant", + "excludesDefault": "Il tenant della piattaforma è escluso da questa azione.", + "searchPlaceholder": "Cerca tenant…", + "loading": "Caricamento tenant…", + "empty": "Nessun tenant corrispondente.", + "targetCount": "Sarà applicato a {{count}} tenant.", + "platformTenant": "piattaforma", + "confirm": "Applica a {{count}} tenant", + "result": { + "succeeded": "Riusciti", + "noneSucceeded": "Nessun tenant riuscito.", + "failed": "Falliti", + "noneFailed": "Nessun errore." + } }, - "graph": { - "nodes_one": "{{count}} nodo", - "nodes_other": "{{count}} nodi", - "edges_one": "{{count}} arco", - "edges_other": "{{count}} archi", - "clickToPivot": "clic per passare", - "malicious": "malevolo", - "unknown": "sconosciuto", - "benign": "inoffensivo" + "tiAnalyst": { + "console": { + "subtitle": "Area analista", + "model": "Modello", + "resizeResults": "Ridimensiona il pannello dei risultati", + "resizeHint": "Trascina per ridimensionare · doppio clic per reimpostare" + }, + "conv": { + "title": "Conversazioni", + "allConversations": "Tutte le conversazioni", + "empty": "Nessuna conversazione al momento.", + "new": "Nuova conversazione", + "newTitle": "Titolo della conversazione", + "selectPrompt": "Seleziona una conversazione o avviane una.", + "running": "in corso", + "delete": "Elimina {{title}}", + "unread_one": "{{count}} messaggio non letto", + "unread_other": "{{count}} messaggi non letti", + "transcript": "Trascrizione della conversazione" + }, + "agent": { + "placeholder": "Indaga su un indicatore…", + "ask": "Chiedi all'agente analista", + "intro": "Chiedi qualsiasi indicatore. L'agente interroga direttamente ThreatWinds e mostra il suo lavoro.", + "send": "Invia", + "stop": "Ferma", + "thinking": "pensiero…", + "suggestionInvestigate": "Indaga su 8.8.8.8 e dimmi se è malevolo", + "suggestionInfrastructure": "Che infrastruttura è collegata a google.com?", + "suggestionCounts": "Mostrami quante entità esistono per tipo" + }, + "canvas": { + "title": "Risultati", + "empty": "I risultati di questa conversazione appaiono qui.", + "tile": "Ordina", + "closeAll": "Chiudi tutto", + "pinOut": "Apri {{title}} come pannello", + "loading": "caricamento…", + "failed": "impossibile caricare", + "noRelations": "nessuna entità correlata", + "noGeo": "nessuna geolocalizzazione registrata", + "noResults": "nessuna corrispondenza", + "matches": "{{total}} corrispondenze", + "panelName": "{{title}} — {{kind}}", + "movePanel": "Sposta {{title}}", + "resizePanel": "Ridimensiona {{title}}", + "closePanel": "Chiudi {{title}}", + "collapse": "Comprimi {{title}}", + "expand": "Espandi {{title}}", + "kind": { + "entity": "dossier", + "graph": "relazioni", + "geo": "geolocalizzazione", + "search": "ricerca" + } + }, + "graph": { + "nodes_one": "{{count}} nodo", + "nodes_other": "{{count}} nodi", + "edges_one": "{{count}} arco", + "edges_other": "{{count}} archi", + "clickToPivot": "clic per passare", + "malicious": "malevolo", + "unknown": "sconosciuto", + "benign": "inoffensivo" + }, + "entity": { + "reputation": "Reputazione", + "accuracy": "Precisione", + "worst": "Peggio", + "best": "Meglio", + "relations": "Grafo delle relazioni", + "history": "Cronologia", + "geolocations": "Geolocalizzazioni", + "associations": "Associazioni", + "radius": "r={{radius}}m", + "askAgentBtn": "Chiedi all'agente", + "askAgent": "Valuta {{type}} {{value}} (entità id {{id}}). È una minaccia?" + }, + "tool": { + "querying": "interrogazione…", + "notRetained": "Risultato non conservato.", + "expand": "Mostra richiesta e risultato", + "collapse": "Nascondi richiesta e risultato", + "noIntel": "«{{value}}» non ha informazioni di minaccia registrate.", + "noMatches": "Nessuna corrispondenza.", + "matches": "{{items}} corrispondenze per «{{query}}»", + "more": "+{{count}} altri", + "reported": "Segnalato al corpus ThreatWinds condiviso. L ingestione e asincrona, non immediatamente ricercabile.", + "skippedAssociations": "Non registrato (tipo non deducibile): {{values}}" + } }, - "entity": { - "reputation": "Reputazione", - "accuracy": "Precisione", - "worst": "Peggio", - "best": "Meglio", - "relations": "Grafo delle relazioni", - "history": "Cronologia", - "geolocations": "Geolocalizzazioni", - "associations": "Associazioni", - "radius": "r={{radius}}m", - "askAgentBtn": "Chiedi all'agente", - "askAgent": "Valuta {{type}} {{value}} (entità id {{id}}). È una minaccia?" + "threatwinds": { + "title": "Integrazione ThreatWinds", + "subtitle": "Condividi gli incidenti di questa istanza con il feed comunitario ThreatWinds.", + "feeds": "Abilita i feed", + "feedsHint": "Quando attivo, gli eventi vengono confrontati con i feed di intelligence di ThreatWinds.", + "contribute": "Contribuisci incidenti", + "contributeHint": "Quando attivo, gli incidenti di questa istanza vengono inviati a ThreatWinds.", + "loading": "Caricamento stato integrazione…", + "failed": "Impossibile caricare lo stato dell'integrazione ThreatWinds.", + "retry": "Riprova", + "toast": { + "enabled": "Contribuzione attivata", + "disabled": "Contribuzione disattivata", + "failed": "Impossibile aggiornare l'impostazione di contribuzione" + } }, - "tool": { - "querying": "interrogazione…", - "notRetained": "Risultato non conservato.", - "expand": "Mostra richiesta e risultato", - "collapse": "Nascondi richiesta e risultato", - "noIntel": "«{{value}}» non ha informazioni di minaccia registrate.", - "noMatches": "Nessuna corrispondenza.", - "matches": "{{items}} corrispondenze per «{{query}}»", - "more": "+{{count}} altri", - "reported": "Segnalato al corpus ThreatWinds condiviso. L ingestione e asincrona, non immediatamente ricercabile.", - "skippedAssociations": "Non registrato (tipo non deducibile): {{values}}" - } - }, - "threatwinds": { - "title": "Integrazione ThreatWinds", - "subtitle": "Condividi gli incidenti di questa istanza con il feed comunitario ThreatWinds.", - "feeds": "Abilita i feed", - "feedsHint": "Quando attivo, gli eventi vengono confrontati con i feed di intelligence di ThreatWinds.", - "contribute": "Contribuisci incidenti", - "contributeHint": "Quando attivo, gli incidenti di questa istanza vengono inviati a ThreatWinds.", - "loading": "Caricamento stato integrazione…", - "failed": "Impossibile caricare lo stato dell'integrazione ThreatWinds.", - "retry": "Riprova", - "toast": { - "enabled": "Contribuzione attivata", - "disabled": "Contribuzione disattivata", - "failed": "Impossibile aggiornare l'impostazione di contribuzione" - } - }, - "liveOps": { - "header": "Operazioni live", - "live": "LIVE", - "replay": "RIPRODUZIONE", - "statLastHour": "Ultima ora", - "statHigh": "Alte", - "statOpen": "Aperte", - "statAttackers": "Attaccanti", - "listTitle": "Avvisi", - "listShown": "{{count}} mostrati", - "listShow": "Mostra l'elenco degli avvisi", - "listHide": "Nascondi l'elenco", - "agoJust": "adesso", - "agoMin": "{{count}} min fa", - "agoH": "{{count}} h fa", - "more": "Di più", - "less": "Di meno", - "loading": "Caricamento avvisi…", - "error": "Impossibile caricare gli avvisi: {{msg}}", - "empty": "Nessun avviso nel repository.", - "onStage": "In scena", - "hideDetails": "Nascondi questo pannello", - "showDetails": "Mostra i dettagli", - "inIncident": "In un incidente", - "openInAlerts": "Apri in Avvisi", - "involved": "Coinvolti", - "askSocAi": "Chiedi a SOC-AI", - "askExplain": "Spiegami questo attacco e dimmi cosa fare dopo", - "askFp": "È un falso positivo?", - "askAttacker": "Cosa ha fatto ancora questo attaccante?", - "timCount": "{{count}} avvisi nelle ultime {{range}}", - "timPrev": "Avviso precedente", - "timNext": "Avviso successivo", - "timReplay": "Riproduci finestra", - "timStop": "Ferma la riproduzione", - "timLive": "LIVE", - "timNow": "adesso", - "kb": { - "bruteForce": "Forza bruta", - "outbound": "Connessione a una destinazione malevola", - "lateral": "Movimento laterale", - "malware": "Esecuzione malevola su un host", - "webAttack": "Attacco web", - "travel": "Viaggio impossibile", - "scan": "Scansione di porte", - "cloud": "Modifica rischiosa nel cloud", - "generic": "Rilevamento", - "ransomware": "Ransomware su un host", - "persistence": "Meccanismo di persistenza", - "exfil": "Esfiltrazione di dati", - "defenseEvasion": "Evasione delle difese", - "privEsc": "Elevazione dei privilegi", - "userExec": "Utente apre un file malevolo", - "softwareDeploy": "Software spinta su un host", - "phishing": "E-mail di phishing aperto", - "processInjection": "Codice iniettato in un processo", - "credDump": "Credenziali rubate", - "dataDestruction": "Dati distrutti", - "toolDownload": "Strumento scaricato ed eseguito", - "c2tunnel": "C2 attraverso un tunnel", - "iocMatch": "IOC di minaccia rilevato", - "perimeterDetect": "Rilevamento perimetro/IDS", - "accountChange": "Modifica account o policy", - "kerberosTicket": "Abuso di ticket Kerberos", - "powershellAbuse": "Abuso di scripting", - "reverseShell": "Shell inversa", - "vmEscape": "Escape VM/ippervisor" + "liveOps": { + "header": "Operazioni live", + "live": "LIVE", + "replay": "RIPRODUZIONE", + "statLastHour": "Ultima ora", + "statHigh": "Alte", + "statOpen": "Aperte", + "statAttackers": "Attaccanti", + "listTitle": "Avvisi", + "listShown": "{{count}} mostrati", + "listShow": "Mostra l'elenco degli avvisi", + "listHide": "Nascondi l'elenco", + "agoJust": "adesso", + "agoMin": "{{count}} min fa", + "agoH": "{{count}} h fa", + "more": "Di più", + "less": "Di meno", + "loading": "Caricamento avvisi…", + "error": "Impossibile caricare gli avvisi: {{msg}}", + "empty": "Nessun avviso nel repository.", + "onStage": "In scena", + "hideDetails": "Nascondi questo pannello", + "showDetails": "Mostra i dettagli", + "inIncident": "In un incidente", + "openInAlerts": "Apri in Avvisi", + "involved": "Coinvolti", + "askSocAi": "Chiedi a SOC-AI", + "askExplain": "Spiegami questo attacco e dimmi cosa fare dopo", + "askFp": "È un falso positivo?", + "askAttacker": "Cosa ha fatto ancora questo attaccante?", + "timCount": "{{count}} avvisi nelle ultime {{range}}", + "timPrev": "Avviso precedente", + "timNext": "Avviso successivo", + "timReplay": "Riproduci finestra", + "timStop": "Ferma la riproduzione", + "timLive": "LIVE", + "timNow": "adesso", + "kb": { + "bruteForce": "Forza bruta", + "outbound": "Connessione a una destinazione malevola", + "lateral": "Movimento laterale", + "malware": "Esecuzione malevola su un host", + "webAttack": "Attacco web", + "travel": "Viaggio impossibile", + "scan": "Scansione di porte", + "cloud": "Modifica rischiosa nel cloud", + "generic": "Rilevamento", + "ransomware": "Ransomware su un host", + "persistence": "Meccanismo di persistenza", + "exfil": "Esfiltrazione di dati", + "defenseEvasion": "Evasione delle difese", + "privEsc": "Elevazione dei privilegi", + "userExec": "Utente apre un file malevolo", + "softwareDeploy": "Software spinta su un host", + "phishing": "E-mail di phishing aperto", + "processInjection": "Codice iniettato in un processo", + "credDump": "Credenziali rubate", + "dataDestruction": "Dati distrutti", + "toolDownload": "Strumento scaricato ed eseguito", + "c2tunnel": "C2 attraverso un tunnel", + "iocMatch": "IOC di minaccia rilevato", + "perimeterDetect": "Rilevamento perimetro/IDS", + "accountChange": "Modifica account o policy", + "kerberosTicket": "Abuso di ticket Kerberos", + "powershellAbuse": "Abuso di scripting", + "reverseShell": "Shell inversa", + "vmEscape": "Escape VM/ippervisor" + }, + "replayTip": "Riproduci tutte le alerte di questa finestra in ordine", + "liveTip": "Segui le nuove alerte man mano che arrivano", + "playAgain": "Riproduci questa allerta di nuovo", + "alertAt": "{{name}} alle {{time}}", + "netInternet": "Internet", + "netInternal": "Rete interna", + "scUser": "utente: {{account}}", + "scWrongPassword": "✕ password errata", + "scSignedIn": "✓ accesso effettuato", + "scSignedInAs": "accesso effettuato come {{account}}", + "scFailedSignins": "Accessi falliti", + "scBlocked": "🛡 {{name}} bloccato", + "scSessionAs": "sessione come {{account}}", + "scHost": "Host · {{name}}", + "scFiles": "Documenti", + "scBackups": "Copie ombra", + "scRansomNote": "🔒 NOTE DI RISCATTO", + "scShadows": "✕ copie ombra eliminate", + "scPersist": "Persistenza", + "scReboot": "sopravvive ai riavvii: backdoor installata", + "scCloud": "Archiviazione esterna", + "scChunk": "dati", + "scExfilBytes": "Dati esfiltrati", + "scProcessTree": "Albero dei processi", + "scDns": "DNS? {{host}}", + "scThreatIntel": "Threat intel: Allarmante (-3)", + "scConnDropped": "✕ connessione interrotta", + "scPortsProbed": "Porte sondati", + "scSignIn": "✓ accesso", + "scKmInMin": "{{km}} km in {{min}} min", + "scAbroad": "all'estero", + "scDropped": "{{status}} bloccato", + "scBeacon": "baliza", + "capBrute0": "{{name}}{{sub}} inizia a indovinare le password contro {{where}}.", + "capBruteVpn": "il VPN su {{name}}", + "capBrute1": "{{attempts}} accessi falliti in {{minutes}} minuti, ruotando {{count}} nomi di account.", + "capBrute2": "Un accesso come {{account}} riesce subito dopo i fallimenti: la password è stata indovinata.", + "capBrute3": "Correlazione dei fallimenti tra le fonti: un attaccante, molti account.", + "capBrute4": "Blocca {{name}} sul perimetro{{reset}}.", + "capBruteReset": " e reimposta {{account}}", + "capOut1": "{{who}} risolve {{dest}}.", + "capOut2": "Si connette in uscita sulla porta {{port}}{{through}}.", + "capOutThrough": " tramite {{name}}", + "capOut3": "La threat intelligence corrisponde a {{dest}}: {{kind}}.", + "capOut4": "La connessione è stata interrotta e l'alerta è stata elevata perché la macchina venga verificata.", + "capOut5": "La connessione si ripete: {{name}} è probabilmente infetto. Isolarlo e trovare il processo.", + "capLat0": "{{name}}{{user}} contatta {{to}} all'interno della rete.", + "capLatUser": " ({{user}})", + "capLat1": "Si autentica come {{account}} usando {{how}}.", + "capLatHowHash": "un hash di password rubato", + "capLatHowKerb": "dei ticket di servizio Kerberos che può decifrare offline", + "capLatHowAsrep": "una risposta Kerberos per un account senza pre-autenticazione", + "capLatHowSmb": "il vecchio protocollo SMBv1", + "capLatHowRdp": "sessioni remote e condivisioni di file", + "capLat2": "{{to}} accetta la sessione: l'attaccante si muove ora tra le macchine.", + "capLat3": "Disabilita {{account}} e controlla entrambe le macchine.", + "capMal0": "Su {{host}}{{user}} viene eseguito {{proc}}.", + "capMalUser": ", {{user}}", + "capMal1": "{{p0}} avvia {{p1}}: insolito per questo programma.", + "capMalChild": "un processo figlio", + "capMal2": "{{name}} viene eseguito: {{detail}}.", + "capMalKnown": "una tecnica di attacco nota", + "capMal3": "Ferma il processo o isola {{host}}.", + "capWeb0": "{{name}} sonda il server su {{to}}.", + "capWeb1": "Invia carichi di attacco: {{payloads}}…", + "capWeb2": "{{perimeter}} riconosce le firme d'attacco e scarta le richieste.", + "capWeb2b": "L'IPS riconosce le firme d'attacco e scarta le richieste.", + "capWeb3": "Alcune richieste raggiungono {{to}}; il server risponde con errori e un 200 OK.", + "capWeb4": "Blocca {{name}} e controlla i log del server.", + "capTrv0": "{{user}} accede da {{city}}, come di solito.", + "capTrv1": "Dopo {{gap}} minuti lo stesso account accede da {{city}}, {{country}}.", + "capTrvFar": "da lontano", + "capTrv2": "{{km}} km in {{gap}} minuti: nessuno viaggia così veloce. La password è probabilmente stata rubata.", + "capTrv3": "Revoca le sessioni e reimposta la password di {{user}}.", + "capScn0": "{{name}} inizia a bussare su {{to}}, una porta dopo l'altra.", + "capScn1": "{{count}} porte sondati in pochi secondi: SSH, SMB, RDP, database, console web…", + "capScn2": "Le porte {{open}} rispondono; il resto è chiuso o filtrato.", + "capScn3": "Di solito il primo passo di un attacco: blocca la sorgente.", + "capCl0": "{{name}} accede a {{cloud}}{{from}}.", + "capClFrom": " da {{country}}", + "capClFromDef": "fuori dall'azienda", + "capCl1": "Modificano {{what}}.", + "capCl3": "Conferma che era pianificato o annullalo.", + "capGen0": "{{src}} → {{tgt}}", + "capGen1": "{{what}}", + "capGenNew": "Nuova rilevazione", + "capGen2": "Allerta elevata: {{name}}.", + "capAlertRaised": "Allerta elevata: {{name}}. ", + "capBlocked": "{{ip}} è ora bloccato su {{on}}: il traffico si ferma qui.", + "destUnknown": "destinazione sconosciuta", + "titleBrute": "Attacco brute force da {{name}} su {{to}}", + "titleOut": "{{name}} contatta {{to}}", + "titleLat": "{{name}} si sposta su {{to}} come {{account}}", + "titleMal": "{{name}} su {{to}}", + "titleWeb": "Attacco web da {{name}} su {{to}}", + "titleTrv": "{{name}} accede da due continenti", + "titleScn": "Scansione porte da {{name}}", + "titleCl": "{{what}} modificato in {{to}}", + "titleAlert": "Allerta", + "dLsass": "scarica la memoria di LSASS per rubare le password", + "dMiner": "minera criptovalute con la CPU del server", + "dRev": "apre una shell interattiva verso l'attaccante", + "dKey": "esporta le password salvate dal keychain", + "dTask": "crea un task che esegue un payload ad ogni accesso", + "dAudit": "cancella il log di sicurezza di Windows", + "dFw": "elimina le regole del firewall dell'host", + "dShadow": "cancella le copie di ombra del volume prima della cifratura", + "dDump": "strumento per estrarre le credenziali", + "dDl": "scarica uno strumento in una cartella scrivibile", + "dPs": "esegue un comando codificato", + "capRan0": "Su {{host}}{{user}}, un processo inizia a toccare centinaia di file in una volta.", + "capRanUser": ", {{user}}", + "capRan1": "I file vengono rinominati con {{exts}}: i dati vengono cifrati sul posto.", + "capRan2": "Viene scritta una nota di riscatto: l’attaccante chiede un pagamento per ripristinare i dati.", + "capRan2b": "I backup e le copie ombra vengono eliminati: nessuna via facile di ritorno.", + "capRan3": "Ripristinare dai backup offline e trovare il punto di ingresso prima che la cifratura si diffonda.", + "titleRan": "Ransomware che cifra {{to}}", + "capPer0": "Su {{host}}{{user}}, qualcosa scrive nelle posizioni di avvio di sistema.", + "capPer1": "Deposita {{what}}: questi si eseguono automaticamente a ogni avvio o accesso.", + "capPer2": "Ultimo pezzo a posto: {{what}}. La presenza sopravvive ora ai riavvii.", + "capPer3": "Rimuovere gli artefatti di persistenza e cercare il vettore di infezione iniziale.", + "titlePer": "Persistenza installata su {{to} via {{what}}", + "dPersistCron": "esegue il payload secondo un pianificatore", + "dPersistSd": "avvia il payload a ogni boot", + "dPersistLaunch": "lancia il payload all’accesso dell’utente", + "dPersistKey": "permette all’attaccante di rientrare via SSH", + "dPersistRc": "esegue il payload in ogni nuova shell", + "dPersistPs": "esegue il payload in ogni sessione PowerShell", + "dPersistPay": "il binario del payload stesso", + "capExf0": "Su {{host}}{{user}}, dati sensibili vengono raccolti in un archivio.", + "capExf1": "Inizia a trasferirli all’esterno usando {{tool}}.", + "capExf2": "I dati arrivano a {{dest}}: ora sono fuori dall’azienda.", + "capExf3": "Bloccare il trasferimento, revocare l’accesso a {{dest}} e capire chi può raggiungerli.", + "titleExf": "{{name}} esfiltra dati verso {{to}}", + "scDefenses": "Difese", + "scDisabled": "✕ disattivato", + "scLogsCleared": "🗑 log cancellati", + "dEvLog": "traccia di audit", + "dEvEnf": "applicazione", + "capEv0": "Su {{host}}, l’attaccante inizia a toccare le cose che lo vigilano.", + "capEv1": "{{what}} viene disattivato: una in meno che può vederlo.", + "capEv2": "I log vengono cancellati: la traccia delle sue azioni scompare.", + "capEv2b": "Con {{what}} disattivato, l’host è cieco davanti all’attaccante.", + "capEv3": "Ripristinare gli strumenti disattivati e preservare i log rimanenti prima che spariscano anche loro.", + "titleEv": "Difese disattivate su {{to}}", + "scNormalUser": "utente normale", + "scToken": "token", + "dEvUac": "UAC aggirata", + "dEvToken": "token impersonato", + "dEvSuid": "binario setuid abusato", + "dEvSudo": "cache di sudo abusato", + "dEvExploit": "kernel sfruttato", + "dEvDefault": "confine dei privilegi oltrepassato", + "capPe0": "Su {{host}}, la sessione gira come utente normale.{{user}}", + "capPeUser": ", {{user}}", + "capPe1": "Usa {{method}} per raggiungere un livello di privilegio superiore.", + "capPe2": "I comandi ora girano come {{account}}: controllo totale dell’host.", + "capPe3": "Terminare la sessione elevata e auditare cosa {{account}} ha potuto toccare.", + "titlePe": "Elevazione dei privilegi su {{to}} via {{method}}", + "alertRaised": "Allerta elevata", + "userExec": "Utente apre un file malevolo", + "softwareDeploy": "Software spinta su un host", + "phishing": "E-mail di phishing aperto", + "processInjection": "Codice iniettato in un processo", + "credDump": "Credenziali rubate", + "dataDestruction": "Dati distrutti", + "toolDownload": "Strumento scaricato ed eseguito", + "c2tunnel": "C2 attraverso un tunnel", + "scExec": "Esecuzione", + "scPayload": "→ payload malevolo", + "capUe0": "Su {{host}}{{user}}, l’utente scarica un file e lo apre.", + "capUeUser": ", {{user}}", + "capUe1": "Il file viene aperto: {{file}} è considerato affidabile ed eseguito.", + "capUe2": "{{app}} avvia un processo figlio che esegue {{payload}}.", + "capUe3": "Mettere il file in quarantena, bloccarne l’hash e controllare gli altri host che lo hanno aperto.", + "titleUe": "{{file}} aperto su {{to}}", + "scDeploy": "Distribuzione", + "capSd0": "{{src}} spinge del software verso {{to}} sulla rete.", + "capSd1": "Usa {{tool}}: un canale che installa senza interazione dell’utente.", + "capSd2": "Il pacchetto viene installato su {{to}} e parte con esso.", + "capSd3": "Fermare la distribuzione, rimuovere il componente installato e auditare cosa ha fatto.", + "titleSd": "Software distribuita da {{src}} a {{to}}", + "scAttachment": "allegato aperto", + "capPh0": "{{name}} invia un e-mail di phishing in azienda.", + "capPh1": "Il messaggio arriva nella casella di {{user}} e viene aperto.", + "capPh2": "L’allegato viene eseguito: {{file}} gira sulla macchina.", + "capPh3": "Mettere l’e-mail in quarantena, bloccare il mittente e rimuovere {{file}} dalla macchina di {{user}}.", + "titlePh": "E-mail di phishing aperta da {{user}} (da {{from}})", + "scInject": "Iniezione", + "scInside": "— codice dentro un processo fidato", + "capPi0": "Su {{host}}, parte il caricatore dell’attaccante: {{injector}}.", + "capPi1": "Inietta codice in un processo fidato: {{victim}}.", + "capPi2": "{{victim}} esegue ora il codice dell’attaccante con i propri privilegi.", + "capPi3": "Uccidere il codice iniettato, rimuovere il caricatore e cercare altre vittime.", + "titlePi": "{{injector}} inietta codice in {{victim}}", + "scCred": "Archivio credenziali", + "scSecrets": "{{n}} segreti", + "scSecret": "segreto", + "scStolen": "✕ credenziali rubate", + "capCd0": "Su {{host}}, uno strumento inizia a leggere l’archivio credenziali.", + "capCd1": "Apre {{store}} ed estrae il materiale memorizzato.", + "capCd2": "Vengono catturate {{n}} credenziali: account, chiavi e hash.", + "capCd3": "Ruotare tutte le credenziali dell’archivio e cercare lo strumento di dump.", + "titleCd": "{{store}} rubato su {{host}}", + "scData": "Dati", + "scDataItem": "dataset-{{i}}", + "scGone": "perso", + "scNoRecovery": "dati distrutti", + "capDd0": "Su {{host}}, qualcosa inizia a cancellare i dati invece di cifrarli.", + "capDd1": "{{n}} dataset vengono distrutti, uno dopo l’altro.", + "capDd2": "I dati vengono eliminati in crudo: niente nota, niente riscatto, niente ritorno.", + "capDd3": "Fermare il processo di origine e ripristinare ciò che resta dai backup offline.", + "titleDd": "Dati distrutti su {{host}}", + "scDownload": "byte", + "scExecuted": "eseguito", + "capTd0": "{{src}} serve uno strumento a {{to}}.", + "capTd1": "Viene scaricato in una cartella scrivibile: {{folder}}.", + "capTd2": "Il file viene eseguito: {{tool}} è ora attivo.", + "capTd3": "Cancellare lo strumento, bloccarne l’hash e verificare quali host lo hanno eseguito.", + "titleTd": "{{src}} depone uno strumento su {{to}}", + "scTunnel": "nascosto nel traffico {{proto}}", + "scTunneled": "Byte instradati", + "capCt0": "{{src}} comunica con {{to}} usando un protocollo dall’aspetto normale.", + "capCt1": "Il payload è nascosto nel traffico {{proto}}.", + "capCt2": "Comandi e dati attraversano il confine invisibili, portati da {{proto}}.", + "capCt3": "Tagliare il tunnel, bloccare l’estremità e controllare cosa ci è passato.", + "titleCt": "{{src}} instrada C2 via {{proto}} verso {{to}}", + "netPerimeter": "Perimetro", + "scDc": "Controller di dominio", + "scObject": "Oggetto modificato", + "scChangedBy": "modificato da", + "scHighRisk": "modifica ad alto rischio", + "scTktAsk": "richiesta ticket", + "scTktUses": "riutilizzato su {{n}} servizi", + "scTerminal": "Terminale", + "scRunning": "…in esecuzione", + "scAmsiOff": "⚠ AMSI disattivato", + "scConn": "TCP {{port}}", + "scShellOn": "$ reverse shell", + "scHypervisor": "Ippervizzatore", + "scGuestVm": "VM guest", + "scConfined": "confinato nel guest", + "scEscaped": "evaso sul host", + "scBoundary": "confine guest oltrepassato", + "scFeedAsk": "feed? {{ioc}}", + "scFeedBad": "CATTIVO", + "scFeedHit": "Intel minacce: {{kind}}", + "scDroppedAtFw": "✕ scartato in {{fw}}", + "scTrafficStops": "il traffico si ferma qui", + "scSigHits": "Hit firma", + "capIoc0": "{{src}} si connette a {{ioc}}.", + "capIoc1": "L’intelligence di minaccia lo flagga: {{kind}}.", + "capIoc2": "{{ioc}} è nella lista di blocco: la connessione è interrotta.", + "capIoc3": "Bloccare {{ioc}} al bordo e controllare cosa è già uscito dalla rete.", + "titleIoc": "{{src}} raggiunge un {{ioc}} noto", + "capPd0": "{{name}} invia una {{sig}} al perimetro.", + "capPd1": "{{fw}} matcha la firma e scatta.", + "capPd2": "Il traffico viene scartato: il perimetro ha retto.", + "capPd3": "Il traffico attraversa {{fw}}: l’allerta è informativa.", + "capPd4": "Verificare la firma e bloccare la fonte se continua a arrivare.", + "titlePd": "{{sig}} bloccato su {{fw}}", + "capAc0": "{{who}} modifica {{what}} su {{host}}.", + "capAc1": "Il {{what}} viene modificato.", + "capAc2": "{{before}} → {{after}}.", + "capAc3": "Confermare che era pianificato o annullare la modifica di {{who}}.", + "titleAc": "{{what}} modificato su {{host}}", + "capKb0": "{{src}} richiede ticket Kerberos a {{dc}}.", + "capKb1": "Il {{ticket}} ottenuto è {{kind}}.", + "capKb2": "Viene riutilizzato su {{services}}: il DC lo accetta ogni volta.", + "capKb3": "Resetare la password krbtgt e auditare i ticket emessi nelle ultime 48 h.", + "titleKb": "{{src}} fabbrica ticket Kerberos via {{dc}}", + "capPs0": "Su {{host}}, uno script parte con contenuto codificato.", + "capPs1": "Decodifica un comando e disattiva il sensore antimalware (AMSI).", + "capPs2": "Il comando decodificato si esegue: è un payload, non uno script.", + "capPs2a": "AMSI è prima disattivato, poi il comando codificato gira inosservato.", + "capPs3": "Bloccare l’hash, cercare altre macchine con lo stesso script.", + "titlePs2": "Script codificato in esecuzione su {{host}}", + "capRs0": "Su {{host}}, un processo apre una socket verso l’esterno.", + "capRs1": "Si riconnette a {{name}} sulla porta {{port}}: una reverse shell.", + "capRs2": "Appare un prompt: l’attaccante può ora digitare comandi sul host.", + "capRs3": "Uccidere la connessione, isolare {{host}} e vedere cosa è stato digitato.", + "titleRs": "Reverse shell aperta su {{host}}", + "capVm0": "La VM guest {{guest}} esegue un processo con accesso a livello host.", + "capVm1": "Tenta di attraversare il confine dell’ippervizzatore.", + "capVm2": "Il processo gira sull’host {{host}}: il guest non è più una gabbia.", + "capVm3": "Panicare l’ippervizzatore, fare uno snapshot del guest e ricostruirlo.", + "titleVm": "Guest {{guest}} che evade su {{host}}", + "listNew": "Nuovo", + "newAlertsCount_one": "{{count}} nuovo alert", + "newAlertsCount_other": "{{count}} nuovi alert", + "statTotal": "Totale", + "timPage": "Pagina {{p}}/{{n}}", + "timPagePrev": "Pagina precedente", + "timPageNext": "Pagina successiva", + "newAlerts": "Nuovi alert" }, - "replayTip": "Riproduci tutte le alerte di questa finestra in ordine", - "liveTip": "Segui le nuove alerte man mano che arrivano", - "playAgain": "Riproduci questa allerta di nuovo", - "alertAt": "{{name}} alle {{time}}", - "netInternet": "Internet", - "netInternal": "Rete interna", - "scUser": "utente: {{account}}", - "scWrongPassword": "✕ password errata", - "scSignedIn": "✓ accesso effettuato", - "scSignedInAs": "accesso effettuato come {{account}}", - "scFailedSignins": "Accessi falliti", - "scBlocked": "🛡 {{name}} bloccato", - "scSessionAs": "sessione come {{account}}", - "scHost": "Host · {{name}}", - "scFiles": "Documenti", - "scBackups": "Copie ombra", - "scRansomNote": "🔒 NOTE DI RISCATTO", - "scShadows": "✕ copie ombra eliminate", - "scPersist": "Persistenza", - "scReboot": "sopravvive ai riavvii: backdoor installata", - "scCloud": "Archiviazione esterna", - "scChunk": "dati", - "scExfilBytes": "Dati esfiltrati", - "scProcessTree": "Albero dei processi", - "scDns": "DNS? {{host}}", - "scThreatIntel": "Threat intel: Allarmante (-3)", - "scConnDropped": "✕ connessione interrotta", - "scPortsProbed": "Porte sondati", - "scSignIn": "✓ accesso", - "scKmInMin": "{{km}} km in {{min}} min", - "scAbroad": "all'estero", - "scDropped": "{{status}} bloccato", - "scBeacon": "baliza", - "capBrute0": "{{name}}{{sub}} inizia a indovinare le password contro {{where}}.", - "capBruteVpn": "il VPN su {{name}}", - "capBrute1": "{{attempts}} accessi falliti in {{minutes}} minuti, ruotando {{count}} nomi di account.", - "capBrute2": "Un accesso come {{account}} riesce subito dopo i fallimenti: la password è stata indovinata.", - "capBrute3": "Correlazione dei fallimenti tra le fonti: un attaccante, molti account.", - "capBrute4": "Blocca {{name}} sul perimetro{{reset}}.", - "capBruteReset": " e reimposta {{account}}", - "capOut1": "{{who}} risolve {{dest}}.", - "capOut2": "Si connette in uscita sulla porta {{port}}{{through}}.", - "capOutThrough": " tramite {{name}}", - "capOut3": "La threat intelligence corrisponde a {{dest}}: {{kind}}.", - "capOut4": "La connessione è stata interrotta e l'alerta è stata elevata perché la macchina venga verificata.", - "capOut5": "La connessione si ripete: {{name}} è probabilmente infetto. Isolarlo e trovare il processo.", - "capLat0": "{{name}}{{user}} contatta {{to}} all'interno della rete.", - "capLatUser": " ({{user}})", - "capLat1": "Si autentica come {{account}} usando {{how}}.", - "capLatHowHash": "un hash di password rubato", - "capLatHowKerb": "dei ticket di servizio Kerberos che può decifrare offline", - "capLatHowAsrep": "una risposta Kerberos per un account senza pre-autenticazione", - "capLatHowSmb": "il vecchio protocollo SMBv1", - "capLatHowRdp": "sessioni remote e condivisioni di file", - "capLat2": "{{to}} accetta la sessione: l'attaccante si muove ora tra le macchine.", - "capLat3": "Disabilita {{account}} e controlla entrambe le macchine.", - "capMal0": "Su {{host}}{{user}} viene eseguito {{proc}}.", - "capMalUser": ", {{user}}", - "capMal1": "{{p0}} avvia {{p1}}: insolito per questo programma.", - "capMalChild": "un processo figlio", - "capMal2": "{{name}} viene eseguito: {{detail}}.", - "capMalKnown": "una tecnica di attacco nota", - "capMal3": "Ferma il processo o isola {{host}}.", - "capWeb0": "{{name}} sonda il server su {{to}}.", - "capWeb1": "Invia carichi di attacco: {{payloads}}…", - "capWeb2": "{{perimeter}} riconosce le firme d'attacco e scarta le richieste.", - "capWeb2b": "L'IPS riconosce le firme d'attacco e scarta le richieste.", - "capWeb3": "Alcune richieste raggiungono {{to}}; il server risponde con errori e un 200 OK.", - "capWeb4": "Blocca {{name}} e controlla i log del server.", - "capTrv0": "{{user}} accede da {{city}}, come di solito.", - "capTrv1": "Dopo {{gap}} minuti lo stesso account accede da {{city}}, {{country}}.", - "capTrvFar": "da lontano", - "capTrv2": "{{km}} km in {{gap}} minuti: nessuno viaggia così veloce. La password è probabilmente stata rubata.", - "capTrv3": "Revoca le sessioni e reimposta la password di {{user}}.", - "capScn0": "{{name}} inizia a bussare su {{to}}, una porta dopo l'altra.", - "capScn1": "{{count}} porte sondati in pochi secondi: SSH, SMB, RDP, database, console web…", - "capScn2": "Le porte {{open}} rispondono; il resto è chiuso o filtrato.", - "capScn3": "Di solito il primo passo di un attacco: blocca la sorgente.", - "capCl0": "{{name}} accede a {{cloud}}{{from}}.", - "capClFrom": " da {{country}}", - "capClFromDef": "fuori dall'azienda", - "capCl1": "Modificano {{what}}.", - "capCl3": "Conferma che era pianificato o annullalo.", - "capGen0": "{{src}} → {{tgt}}", - "capGen1": "{{what}}", - "capGenNew": "Nuova rilevazione", - "capGen2": "Allerta elevata: {{name}}.", - "capAlertRaised": "Allerta elevata: {{name}}. ", - "capBlocked": "{{ip}} è ora bloccato su {{on}}: il traffico si ferma qui.", - "destUnknown": "destinazione sconosciuta", - "titleBrute": "Attacco brute force da {{name}} su {{to}}", - "titleOut": "{{name}} contatta {{to}}", - "titleLat": "{{name}} si sposta su {{to}} come {{account}}", - "titleMal": "{{name}} su {{to}}", - "titleWeb": "Attacco web da {{name}} su {{to}}", - "titleTrv": "{{name}} accede da due continenti", - "titleScn": "Scansione porte da {{name}}", - "titleCl": "{{what}} modificato in {{to}}", - "titleAlert": "Allerta", - "dLsass": "scarica la memoria di LSASS per rubare le password", - "dMiner": "minera criptovalute con la CPU del server", - "dRev": "apre una shell interattiva verso l'attaccante", - "dKey": "esporta le password salvate dal keychain", - "dTask": "crea un task che esegue un payload ad ogni accesso", - "dAudit": "cancella il log di sicurezza di Windows", - "dFw": "elimina le regole del firewall dell'host", - "dShadow": "cancella le copie di ombra del volume prima della cifratura", - "dDump": "strumento per estrarre le credenziali", - "dDl": "scarica uno strumento in una cartella scrivibile", - "dPs": "esegue un comando codificato", - "capRan0": "Su {{host}}{{user}}, un processo inizia a toccare centinaia di file in una volta.", - "capRanUser": ", {{user}}", - "capRan1": "I file vengono rinominati con {{exts}}: i dati vengono cifrati sul posto.", - "capRan2": "Viene scritta una nota di riscatto: l’attaccante chiede un pagamento per ripristinare i dati.", - "capRan2b": "I backup e le copie ombra vengono eliminati: nessuna via facile di ritorno.", - "capRan3": "Ripristinare dai backup offline e trovare il punto di ingresso prima che la cifratura si diffonda.", - "titleRan": "Ransomware che cifra {{to}}", - "capPer0": "Su {{host}}{{user}}, qualcosa scrive nelle posizioni di avvio di sistema.", - "capPer1": "Deposita {{what}}: questi si eseguono automaticamente a ogni avvio o accesso.", - "capPer2": "Ultimo pezzo a posto: {{what}}. La presenza sopravvive ora ai riavvii.", - "capPer3": "Rimuovere gli artefatti di persistenza e cercare il vettore di infezione iniziale.", - "titlePer": "Persistenza installata su {{to} via {{what}}", - "dPersistCron": "esegue il payload secondo un pianificatore", - "dPersistSd": "avvia il payload a ogni boot", - "dPersistLaunch": "lancia il payload all’accesso dell’utente", - "dPersistKey": "permette all’attaccante di rientrare via SSH", - "dPersistRc": "esegue il payload in ogni nuova shell", - "dPersistPs": "esegue il payload in ogni sessione PowerShell", - "dPersistPay": "il binario del payload stesso", - "capExf0": "Su {{host}}{{user}}, dati sensibili vengono raccolti in un archivio.", - "capExf1": "Inizia a trasferirli all’esterno usando {{tool}}.", - "capExf2": "I dati arrivano a {{dest}}: ora sono fuori dall’azienda.", - "capExf3": "Bloccare il trasferimento, revocare l’accesso a {{dest}} e capire chi può raggiungerli.", - "titleExf": "{{name}} esfiltra dati verso {{to}}", - "scDefenses": "Difese", - "scDisabled": "✕ disattivato", - "scLogsCleared": "🗑 log cancellati", - "dEvLog": "traccia di audit", - "dEvEnf": "applicazione", - "capEv0": "Su {{host}}, l’attaccante inizia a toccare le cose che lo vigilano.", - "capEv1": "{{what}} viene disattivato: una in meno che può vederlo.", - "capEv2": "I log vengono cancellati: la traccia delle sue azioni scompare.", - "capEv2b": "Con {{what}} disattivato, l’host è cieco davanti all’attaccante.", - "capEv3": "Ripristinare gli strumenti disattivati e preservare i log rimanenti prima che spariscano anche loro.", - "titleEv": "Difese disattivate su {{to}}", - "scNormalUser": "utente normale", - "scToken": "token", - "dEvUac": "UAC aggirata", - "dEvToken": "token impersonato", - "dEvSuid": "binario setuid abusato", - "dEvSudo": "cache di sudo abusato", - "dEvExploit": "kernel sfruttato", - "dEvDefault": "confine dei privilegi oltrepassato", - "capPe0": "Su {{host}}, la sessione gira come utente normale.{{user}}", - "capPeUser": ", {{user}}", - "capPe1": "Usa {{method}} per raggiungere un livello di privilegio superiore.", - "capPe2": "I comandi ora girano come {{account}}: controllo totale dell’host.", - "capPe3": "Terminare la sessione elevata e auditare cosa {{account}} ha potuto toccare.", - "titlePe": "Elevazione dei privilegi su {{to}} via {{method}}", - "alertRaised": "Allerta elevata", - "userExec": "Utente apre un file malevolo", - "softwareDeploy": "Software spinta su un host", - "phishing": "E-mail di phishing aperto", - "processInjection": "Codice iniettato in un processo", - "credDump": "Credenziali rubate", - "dataDestruction": "Dati distrutti", - "toolDownload": "Strumento scaricato ed eseguito", - "c2tunnel": "C2 attraverso un tunnel", "scExec": "Esecuzione", "scPayload": "→ payload malevolo", "capUe0": "Su {{host}}{{user}}, l’utente scarica un file e lo apre.", @@ -6512,133 +6664,5 @@ "capCt1": "Il payload è nascosto nel traffico {{proto}}.", "capCt2": "Comandi e dati attraversano il confine invisibili, portati da {{proto}}.", "capCt3": "Tagliare il tunnel, bloccare l’estremità e controllare cosa ci è passato.", - "titleCt": "{{src}} instrada C2 via {{proto}} verso {{to}}", - "netPerimeter": "Perimetro", - "scDc": "Controller di dominio", - "scObject": "Oggetto modificato", - "scChangedBy": "modificato da", - "scHighRisk": "modifica ad alto rischio", - "scTktAsk": "richiesta ticket", - "scTktUses": "riutilizzato su {{n}} servizi", - "scTerminal": "Terminale", - "scRunning": "…in esecuzione", - "scAmsiOff": "⚠ AMSI disattivato", - "scConn": "TCP {{port}}", - "scShellOn": "$ reverse shell", - "scHypervisor": "Ippervizzatore", - "scGuestVm": "VM guest", - "scConfined": "confinato nel guest", - "scEscaped": "evaso sul host", - "scBoundary": "confine guest oltrepassato", - "scFeedAsk": "feed? {{ioc}}", - "scFeedBad": "CATTIVO", - "scFeedHit": "Intel minacce: {{kind}}", - "scDroppedAtFw": "✕ scartato in {{fw}}", - "scTrafficStops": "il traffico si ferma qui", - "scSigHits": "Hit firma", - "capIoc0": "{{src}} si connette a {{ioc}}.", - "capIoc1": "L’intelligence di minaccia lo flagga: {{kind}}.", - "capIoc2": "{{ioc}} è nella lista di blocco: la connessione è interrotta.", - "capIoc3": "Bloccare {{ioc}} al bordo e controllare cosa è già uscito dalla rete.", - "titleIoc": "{{src}} raggiunge un {{ioc}} noto", - "capPd0": "{{name}} invia una {{sig}} al perimetro.", - "capPd1": "{{fw}} matcha la firma e scatta.", - "capPd2": "Il traffico viene scartato: il perimetro ha retto.", - "capPd3": "Il traffico attraversa {{fw}}: l’allerta è informativa.", - "capPd4": "Verificare la firma e bloccare la fonte se continua a arrivare.", - "titlePd": "{{sig}} bloccato su {{fw}}", - "capAc0": "{{who}} modifica {{what}} su {{host}}.", - "capAc1": "Il {{what}} viene modificato.", - "capAc2": "{{before}} → {{after}}.", - "capAc3": "Confermare che era pianificato o annullare la modifica di {{who}}.", - "titleAc": "{{what}} modificato su {{host}}", - "capKb0": "{{src}} richiede ticket Kerberos a {{dc}}.", - "capKb1": "Il {{ticket}} ottenuto è {{kind}}.", - "capKb2": "Viene riutilizzato su {{services}}: il DC lo accetta ogni volta.", - "capKb3": "Resetare la password krbtgt e auditare i ticket emessi nelle ultime 48 h.", - "titleKb": "{{src}} fabbrica ticket Kerberos via {{dc}}", - "capPs0": "Su {{host}}, uno script parte con contenuto codificato.", - "capPs1": "Decodifica un comando e disattiva il sensore antimalware (AMSI).", - "capPs2": "Il comando decodificato si esegue: è un payload, non uno script.", - "capPs2a": "AMSI è prima disattivato, poi il comando codificato gira inosservato.", - "capPs3": "Bloccare l’hash, cercare altre macchine con lo stesso script.", - "titlePs2": "Script codificato in esecuzione su {{host}}", - "capRs0": "Su {{host}}, un processo apre una socket verso l’esterno.", - "capRs1": "Si riconnette a {{name}} sulla porta {{port}}: una reverse shell.", - "capRs2": "Appare un prompt: l’attaccante può ora digitare comandi sul host.", - "capRs3": "Uccidere la connessione, isolare {{host}} e vedere cosa è stato digitato.", - "titleRs": "Reverse shell aperta su {{host}}", - "capVm0": "La VM guest {{guest}} esegue un processo con accesso a livello host.", - "capVm1": "Tenta di attraversare il confine dell’ippervizzatore.", - "capVm2": "Il processo gira sull’host {{host}}: il guest non è più una gabbia.", - "capVm3": "Panicare l’ippervizzatore, fare uno snapshot del guest e ricostruirlo.", - "titleVm": "Guest {{guest}} che evade su {{host}}", - "listNew": "Nuovo", - "newAlertsCount_one": "{{count}} nuovo alert", - "newAlertsCount_other": "{{count}} nuovi alert", - "statTotal": "Totale", - "timPage": "Pagina {{p}}/{{n}}", - "timPagePrev": "Pagina precedente", - "timPageNext": "Pagina successiva", - "newAlerts": "Nuovi alert" - }, - "scExec": "Esecuzione", - "scPayload": "→ payload malevolo", - "capUe0": "Su {{host}}{{user}}, l’utente scarica un file e lo apre.", - "capUeUser": ", {{user}}", - "capUe1": "Il file viene aperto: {{file}} è considerato affidabile ed eseguito.", - "capUe2": "{{app}} avvia un processo figlio che esegue {{payload}}.", - "capUe3": "Mettere il file in quarantena, bloccarne l’hash e controllare gli altri host che lo hanno aperto.", - "titleUe": "{{file}} aperto su {{to}}", - "scDeploy": "Distribuzione", - "capSd0": "{{src}} spinge del software verso {{to}} sulla rete.", - "capSd1": "Usa {{tool}}: un canale che installa senza interazione dell’utente.", - "capSd2": "Il pacchetto viene installato su {{to}} e parte con esso.", - "capSd3": "Fermare la distribuzione, rimuovere il componente installato e auditare cosa ha fatto.", - "titleSd": "Software distribuita da {{src}} a {{to}}", - "scAttachment": "allegato aperto", - "capPh0": "{{name}} invia un e-mail di phishing in azienda.", - "capPh1": "Il messaggio arriva nella casella di {{user}} e viene aperto.", - "capPh2": "L’allegato viene eseguito: {{file}} gira sulla macchina.", - "capPh3": "Mettere l’e-mail in quarantena, bloccare il mittente e rimuovere {{file}} dalla macchina di {{user}}.", - "titlePh": "E-mail di phishing aperta da {{user}} (da {{from}})", - "scInject": "Iniezione", - "scInside": "— codice dentro un processo fidato", - "capPi0": "Su {{host}}, parte il caricatore dell’attaccante: {{injector}}.", - "capPi1": "Inietta codice in un processo fidato: {{victim}}.", - "capPi2": "{{victim}} esegue ora il codice dell’attaccante con i propri privilegi.", - "capPi3": "Uccidere il codice iniettato, rimuovere il caricatore e cercare altre vittime.", - "titlePi": "{{injector}} inietta codice in {{victim}}", - "scCred": "Archivio credenziali", - "scSecrets": "{{n}} segreti", - "scSecret": "segreto", - "scStolen": "✕ credenziali rubate", - "capCd0": "Su {{host}}, uno strumento inizia a leggere l’archivio credenziali.", - "capCd1": "Apre {{store}} ed estrae il materiale memorizzato.", - "capCd2": "Vengono catturate {{n}} credenziali: account, chiavi e hash.", - "capCd3": "Ruotare tutte le credenziali dell’archivio e cercare lo strumento di dump.", - "titleCd": "{{store}} rubato su {{host}}", - "scData": "Dati", - "scDataItem": "dataset-{{i}}", - "scGone": "perso", - "scNoRecovery": "dati distrutti", - "capDd0": "Su {{host}}, qualcosa inizia a cancellare i dati invece di cifrarli.", - "capDd1": "{{n}} dataset vengono distrutti, uno dopo l’altro.", - "capDd2": "I dati vengono eliminati in crudo: niente nota, niente riscatto, niente ritorno.", - "capDd3": "Fermare il processo di origine e ripristinare ciò che resta dai backup offline.", - "titleDd": "Dati distrutti su {{host}}", - "scDownload": "byte", - "scExecuted": "eseguito", - "capTd0": "{{src}} serve uno strumento a {{to}}.", - "capTd1": "Viene scaricato in una cartella scrivibile: {{folder}}.", - "capTd2": "Il file viene eseguito: {{tool}} è ora attivo.", - "capTd3": "Cancellare lo strumento, bloccarne l’hash e verificare quali host lo hanno eseguito.", - "titleTd": "{{src}} depone uno strumento su {{to}}", - "scTunnel": "nascosto nel traffico {{proto}}", - "scTunneled": "Byte instradati", - "capCt0": "{{src}} comunica con {{to}} usando un protocollo dall’aspetto normale.", - "capCt1": "Il payload è nascosto nel traffico {{proto}}.", - "capCt2": "Comandi e dati attraversano il confine invisibili, portati da {{proto}}.", - "capCt3": "Tagliare il tunnel, bloccare l’estremità e controllare cosa ci è passato.", - "titleCt": "{{src}} instrada C2 via {{proto}} verso {{to}}" + "titleCt": "{{src}} instrada C2 via {{proto}} verso {{to}}" } diff --git a/frontend/src/shared/i18n/locales/pt.json b/frontend/src/shared/i18n/locales/pt.json index 1d41359f6..38709b7c3 100644 --- a/frontend/src/shared/i18n/locales/pt.json +++ b/frontend/src/shared/i18n/locales/pt.json @@ -1,6459 +1,6611 @@ { - "onboarding": { - "adminEmail": { - "title": "Defina o e-mail do administrador", - "subtitle": "Obrigatório antes de continuar", - "description": "Sua conta de administrador ainda usa o e-mail padrão. Defina um endereço real — ele é necessário para recuperação de senha, notificações e e-mails de alerta.", - "emailLabel": "Endereço de e-mail", - "save": "Salvar e continuar", - "saving": "Salvando…", - "success": "E-mail do administrador definido. Agora configure seu servidor de e-mail.", - "error": "Não foi possível salvar seu e-mail. Tente novamente." - } - }, - "common": { - "appName": "UTMStack", - "language": "Idioma", - "actions": { - "save": "Salvar", - "cancel": "Cancelar", - "retry": "Tentar novamente", - "refresh": "Atualizar", - "delete": "Excluir", - "remove": "Remover", - "close": "Fechar", - "next": "Próximo", - "back": "Voltar" - }, - "confirm": { - "delete": "Excluir", - "working": "Processando…" - }, - "dateRange": { - "pick": "Escolher um intervalo", - "clear": "Limpar", - "done": "Concluir", - "apply": "Aplicar" - }, - "loadingMore": "Carregando mais…", - "allLoaded": "Todos os {{count}} carregados", - "startFrom": { - "scratch": "Do zero", - "scratchHint": "Uma definição vazia preenchida por você.", - "copy": "De uma existente", - "copyHint": "Copia-se tudo exceto o identificador e o nome.", - "pickTitle": "Escolha o que copiar", - "back": "Voltar", - "count": "{{n}} disponíveis", - "search": "Buscar por nome", - "none": "Nada corresponde a essa busca" - }, - "cancel": "Cancelar" - }, - "auth": { - "login": { - "title": "Bem-vindo de volta", - "subtitle": "Entre para continuar no {{brand}}", - "loginLabel": "E-mail", - "passwordLabel": "Senha", - "forgot": "Esqueceu?", - "submit": "Entrar", - "terms": "Ao entrar, você aceita os termos de serviço da {{brand}}.", - "orContinueWith": "ou continue com", - "continueWith": "Continuar com {{name}}", - "signingInTo": "Entrando em {{name}}", - "useAnother": "Usar outro" - }, - "tfa": { - "title": "Verificação em duas etapas", - "subtitleTotp": "Digite o código de 6 dígitos do seu app autenticador.", - "subtitleEmail": "Digite o código de 6 dígitos que enviamos por e-mail.", - "codeLabel": "Código de verificação", - "submit": "Verificar", - "back": "Voltar para o login" + "onboarding": { + "adminEmail": { + "title": "Defina o e-mail do administrador", + "subtitle": "Obrigatório antes de continuar", + "description": "Sua conta de administrador ainda usa o e-mail padrão. Defina um endereço real — ele é necessário para recuperação de senha, notificações e e-mails de alerta.", + "emailLabel": "Endereço de e-mail", + "save": "Salvar e continuar", + "saving": "Salvando…", + "success": "E-mail do administrador definido. Agora configure seu servidor de e-mail.", + "error": "Não foi possível salvar seu e-mail. Tente novamente." + } }, - "forgot": { - "title": "Redefinir senha", - "subtitle": "Enviaremos um link por e-mail para definir uma nova senha.", - "emailLabel": "E-mail", - "submit": "Enviar link", - "sent": "Se esse e-mail estiver registrado, o link de redefinição está a caminho." + "common": { + "appName": "UTMStack", + "language": "Idioma", + "actions": { + "save": "Salvar", + "cancel": "Cancelar", + "retry": "Tentar novamente", + "refresh": "Atualizar", + "delete": "Excluir", + "remove": "Remover", + "close": "Fechar", + "next": "Próximo", + "back": "Voltar" + }, + "confirm": { + "delete": "Excluir", + "working": "Processando…" + }, + "dateRange": { + "pick": "Escolher um intervalo", + "clear": "Limpar", + "done": "Concluir", + "apply": "Aplicar" + }, + "loadingMore": "Carregando mais…", + "allLoaded": "Todos os {{count}} carregados", + "startFrom": { + "scratch": "Do zero", + "scratchHint": "Uma definição vazia preenchida por você.", + "copy": "De uma existente", + "copyHint": "Copia-se tudo exceto o identificador e o nome.", + "pickTitle": "Escolha o que copiar", + "back": "Voltar", + "count": "{{n}} disponíveis", + "search": "Buscar por nome", + "none": "Nada corresponde a essa busca" + }, + "cancel": "Cancelar" + }, + "auth": { + "login": { + "title": "Bem-vindo de volta", + "subtitle": "Entre para continuar no {{brand}}", + "loginLabel": "E-mail", + "passwordLabel": "Senha", + "forgot": "Esqueceu?", + "submit": "Entrar", + "terms": "Ao entrar, você aceita os termos de serviço da {{brand}}.", + "orContinueWith": "ou continue com", + "continueWith": "Continuar com {{name}}", + "signingInTo": "Entrando em {{name}}", + "useAnother": "Usar outro" + }, + "tfa": { + "title": "Verificação em duas etapas", + "subtitleTotp": "Digite o código de 6 dígitos do seu app autenticador.", + "subtitleEmail": "Digite o código de 6 dígitos que enviamos por e-mail.", + "codeLabel": "Código de verificação", + "submit": "Verificar", + "back": "Voltar para o login" + }, + "forgot": { + "title": "Redefinir senha", + "subtitle": "Enviaremos um link por e-mail para definir uma nova senha.", + "emailLabel": "E-mail", + "submit": "Enviar link", + "sent": "Se esse e-mail estiver registrado, o link de redefinição está a caminho." + }, + "errors": { + "tooManyAttempts": "Muitas tentativas. Tente novamente em alguns minutos.", + "deactivated": "Esta conta está desativada.", + "invalidCredentials": "Credenciais inválidas.", + "codeExpired": "Este código expirou. Entre novamente.", + "loginFailed": "Falha ao entrar. Tente novamente.", + "invalidCode": "Código inválido ou expirado.", + "verifyFailed": "A verificação falhou. Tente novamente.", + "resetFailed": "Não foi possível enviar o e-mail de redefinição. Tente novamente.", + "ssoFailed": "O login único não foi concluído. Tente novamente ou use sua senha." + } }, - "errors": { - "tooManyAttempts": "Muitas tentativas. Tente novamente em alguns minutos.", - "deactivated": "Esta conta está desativada.", - "invalidCredentials": "Credenciais inválidas.", - "codeExpired": "Este código expirou. Entre novamente.", - "loginFailed": "Falha ao entrar. Tente novamente.", - "invalidCode": "Código inválido ou expirado.", - "verifyFailed": "A verificação falhou. Tente novamente.", - "resetFailed": "Não foi possível enviar o e-mail de redefinição. Tente novamente.", - "ssoFailed": "O login único não foi concluído. Tente novamente ou use sua senha." - } - }, - "profile": { - "hero": { - "administrator": "Administrador", - "changeAvatar": "Alterar avatar", - "removeAvatar": "Remover avatar" + "profile": { + "hero": { + "administrator": "Administrador", + "changeAvatar": "Alterar avatar", + "removeAvatar": "Remover avatar" + }, + "personal": { + "title": "Informações pessoais", + "description": "Atualize seu nome e dados de contato.", + "firstName": "Nome", + "lastName": "Sobrenome", + "email": "E-mail", + "language": "Idioma", + "languageHint": "Usado na interface do painel.", + "systemDefault": "Padrão do sistema", + "username": "Usuário", + "usernameHint": "O usuário não pode ser alterado.", + "reset": "Redefinir", + "save": "Salvar alterações", + "saving": "Salvando…", + "name": "Nome" + }, + "password": { + "title": "Senha", + "description": "Use uma senha forte que você não reutilize em nenhum outro lugar.", + "current": "Senha atual", + "new": "Nova senha", + "newHint": "Pelo menos 8 caracteres.", + "confirm": "Confirmar nova senha", + "update": "Atualizar senha", + "updating": "Atualizando…" + }, + "sessions": { + "title": "Sessões ativas", + "description": "Dispositivos atualmente conectados à sua conta.", + "loading": "Carregando sessões…", + "empty": "Nenhuma sessão ativa.", + "thisDevice": "Este dispositivo", + "unknownIp": "IP desconhecido", + "unknownDevice": "Dispositivo desconhecido", + "deviceLabel": "{{browser}} em {{os}}", + "signedIn": "Conectado {{time}}", + "revoke": "Revogar", + "revoking": "Revogando…", + "signOutOthers": "Encerrar todas as outras sessões", + "signingOut": "Encerrando…" + }, + "tfa": { + "title": "Autenticação em duas etapas", + "description": "Adicione uma camada extra de segurança à sua conta.", + "loading": "Carregando…", + "methodTotp": "App autenticador", + "methodEmail": "Código por e-mail", + "onTitle": "A autenticação em duas etapas está ativada", + "method": "Método: {{method}}", + "configured": "Configurado", + "disable": "Desativar", + "disableTitle": "Desativar autenticação em duas etapas", + "disableDescription": "Digite sua senha atual para confirmar. Sua conta dependerá apenas da senha depois disso.", + "currentPasswordPlaceholder": "Senha atual", + "disableConfirm": "Desativar 2FA", + "disabling": "Desativando…", + "offTitle": "A autenticação em duas etapas está desativada", + "status": "Status:", + "notConfigured": "Não configurado", + "enable": "Ativar", + "chooseMethod": "Escolha um método", + "totpDesc": "Use Google Authenticator, 1Password, etc. Recomendado.", + "emailDesc": "Receba um código de 6 dígitos por e-mail ao entrar.", + "noEmailHint": "Adicione um e-mail ao seu perfil para usar o método por e-mail.", + "continue": "Continuar", + "starting": "Iniciando…", + "scanTitle": "Escaneie o código QR", + "scanDescription": "Escaneie com seu app autenticador e digite o código de 6 dígitos que ele mostra.", + "manualKey": "Ou digite esta chave manualmente:", + "checkEmailTitle": "Verifique seu e-mail", + "checkEmailDescription": "Enviamos um código de 6 dígitos para {{email}}. Digite-o abaixo.", + "resend": "Reenviar", + "verifyEnable": "Verificar e ativar", + "verifying": "Verificando…" + }, + "actions": { + "cancel": "Cancelar" + }, + "toast": { + "profileUpdated": "Perfil atualizado", + "emailInUse": "Esse e-mail já está em uso", + "profileUpdateFailed": "Não foi possível atualizar o perfil", + "passwordsNoMatch": "As senhas não coincidem", + "passwordTooShort": "A senha deve ter pelo menos 8 caracteres", + "passwordChanged": "Senha alterada — as outras sessões foram encerradas", + "currentPasswordWrong": "A senha atual está incorreta", + "passwordChangeFailed": "Não foi possível alterar a senha", + "avatarTypeNotAllowed": "Tipo de imagem não permitido (use PNG, JPEG, WEBP ou GIF)", + "avatarTooLarge": "A imagem é muito grande (máx. 2MB)", + "avatarUpdated": "Avatar atualizado", + "avatarUploadFailed": "Não foi possível enviar o avatar", + "avatarRemoved": "Avatar removido", + "avatarRemoveFailed": "Não foi possível remover o avatar", + "sessionsLoadFailed": "Não foi possível carregar as sessões", + "sessionRevoked": "Sessão revogada", + "sessionRevokeFailed": "Não foi possível revogar a sessão", + "othersSignedOut": "As outras sessões foram encerradas", + "othersRevokeFailed": "Não foi possível revogar as sessões", + "tfaEmailCodeSent": "Enviamos um código de 6 dígitos para seu e-mail", + "tfaNewCodeSent": "Um novo código foi enviado", + "tfaWaitResend": "Aguarde um momento antes de pedir um novo código", + "tfaResendFailed": "Não foi possível reenviar o código", + "tfaEnterCode": "Digite o código de 6 dígitos", + "tfaEnabled": "Autenticação em duas etapas ativada", + "tfaEnterPassword": "Digite sua senha atual", + "tfaDisabled": "Autenticação em duas etapas desativada", + "tfaDisableFailed": "Não foi possível desativar o 2FA", + "tfaInvalidCode": "Código inválido ou expirado", + "tfaAlreadyEnabled": "O 2FA já está ativado", + "tfaTooManyRequests": "Muitas solicitações; tente novamente em instantes", + "tfaVerifyFailed": "Não foi possível verificar o código", + "genericError": "Algo deu errado", + "tfaMailUnavailable": "O segundo fator por e-mail precisa de um servidor de e-mail. Configure-o em Configurações → Configuração de e-mail." + } }, - "personal": { - "title": "Informações pessoais", - "description": "Atualize seu nome e dados de contato.", - "firstName": "Nome", - "lastName": "Sobrenome", - "email": "E-mail", - "language": "Idioma", - "languageHint": "Usado na interface do painel.", - "systemDefault": "Padrão do sistema", - "username": "Usuário", - "usernameHint": "O usuário não pode ser alterado.", - "reset": "Redefinir", - "save": "Salvar alterações", - "saving": "Salvando…", - "name": "Nome" + "home": { + "hero": { + "title": "O que você gostaria de saber a partir dos seus dados de segurança?", + "placeholder": "Pesquise o Scattered Spider, isso se aplica a nós?, já fomos atacados?, crie uma regra de detecção e mantenha-a ajustada.", + "send": "Enviar", + "suggestions": { + "threatHunt": "Caça a ameaças", + "observableTriage": "Triagem de observáveis", + "writeRule": "Escrever uma regra", + "systemStatus": "Status atual do sistema" + } + }, + "kpis": { + "alerts24h": "Alertas (24 h)", + "openIncidents": "Incidentes abertos", + "openIncidentsSub": "abertos no momento", + "highSeverity24h": "Severidade alta (24 h)", + "highSeveritySub": "de {{n}} alertas", + "activePlaybooks": "Playbooks ativos", + "activePlaybooksSub": "habilitados" + }, + "datasources": { + "title": "Fontes de dados", + "viewAll": "Ver tudo", + "ofTotal": "de {{n}}", + "datasources": "fontes de dados", + "sendingData": "enviando dados", + "totalEvents": "Total de eventos", + "noData": "Sem dados de ingestão nesta janela" + }, + "span": { + "recent": "janela recente", + "days_one": "último {{count}} dia", + "days_other": "últimos {{count}} dias", + "hours": "últimas {{n}} h" + }, + "mitre": { + "title": "Principais técnicas MITRE ATT&CK", + "explore": "Explorar", + "empty": "Ainda não há alertas com técnica atribuída" + }, + "assets": { + "title": "Ativos mais visados", + "viewAll": "Ver tudo", + "asset": "Ativo", + "alerts": "Alertas", + "empty": "Nenhum ativo visado nos alertas recentes" + }, + "compliance": { + "title": "Pontuação de conformidade", + "reports": "Relatórios", + "empty": "Nenhum relatório de conformidade gerado ainda" + }, + "health": { + "title": "Integridade do sistema", + "details": "Detalhes", + "services": { + "backend": "API do backend", + "opensearch": "Cluster do OpenSearch", + "socai": "Motor SOC-AI" + }, + "detail": { + "noClusterInfo": "sem informações do cluster", + "disabled": "desabilitado", + "tools": "{{n}} ferramentas", + "unreachable": "inacessível", + "pending": "…" + } + } }, - "password": { - "title": "Senha", - "description": "Use uma senha forte que você não reutilize em nenhum outro lugar.", - "current": "Senha atual", - "new": "Nova senha", - "newHint": "Pelo menos 8 caracteres.", - "confirm": "Confirmar nova senha", - "update": "Atualizar senha", - "updating": "Atualizando…" + "nav": { + "home": "Início", + "dashboards": "Painéis", + "dashboardList": "Lista de painéis", + "visualizationList": "Widgets", + "newDashboard": "Novo painel", + "newVisualization": "Novo widget", + "threatManagement": "Gestão de ameaças", + "alerts": "Alertas", + "incidents": "Incidentes", + "adversaryView": "Visão de adversários", + "soar": "SOAR", + "flows": "Fluxos", + "executionHistory": "Histórico de execuções", + "interactiveConsole": "Console interativo", + "logExplorer": "Explorador de logs", + "userAuditor": "Auditor de usuários", + "threatIntelligence": "Inteligência de ameaças", + "threat-intel": { + "indicators": "Indicadores", + "analyzt": "Analista de IA", + "triage": "Triagem", + "report": "Relatório" + }, + "compliance": "Conformidade", + "configure": "Configurar", + "dataSources": "Fontes de dados", + "integrations": "Integrações", + "alertingRules": "Regras de alerta", + "dataProcessing": "Processamento de dados", + "team": "Equipe", + "settings": "Configurações", + "back": "Voltar", + "parsingFilters": "Pipelines", + "regexPatterns": "Expressões regulares", + "taggingRules": "Regras de Marcação", + "overview": "Visão geral", + "tenants": "Tenants", + "openMenu": "Abrir menu", + "closeMenu": "Fechar menu", + "liveOps": "Operações ao vivo" + }, + "dashboards": { + "title": "Painéis", + "subtitle": "Navegue e edite painéis interativos.", + "list": { + "title": "Painéis", + "create": "Novo", + "searchPlaceholder": "Pesquisar painéis…", + "loading": "Carregando painéis…", + "empty": "Ainda não há painéis.", + "rename": "Renomear", + "delete": "Excluir" + }, + "actions": { + "edit": "Editar", + "editWithAi": "Editar com IA" + }, + "refresh": { + "title": "Atualização automática", + "options": { + "off": "Desativado", + "10s": "10s", + "30s": "30s", + "1m": "1m", + "5m": "5m", + "15m": "15m" + } + }, + "editor": { + "editing": "Edição", + "addWidget": "Adicionar widget", + "save": "Salvar", + "discard": "Descartar", + "newTitle": "Novo widget", + "newSubtitle": "Escolha um tipo de gráfico, selecione uma fonte de dados e modele-o visualmente. O SQL é gerado automaticamente.", + "editTitle": "Editar widget", + "editSubtitle": "Ajuste a definição do gráfico. As alterações são aplicadas em todos os lugares em que este widget é usado.", + "loading": "Carregando widget…", + "notFoundTitle": "Widget não encontrado", + "notFoundSubtitle": "Pode ter sido excluída ou você não tem acesso a ela.", + "backToDashboard": "Voltar para o painel", + "chartType": { + "title": "Tipo de gráfico" + }, + "chartTypes": { + "bar": { + "label": "Barras", + "description": "Compare valores entre categorias." + }, + "line": { + "label": "Linha", + "description": "Tendências sobre um eixo ordenado." + }, + "area": { + "label": "Área", + "description": "Linha preenchida — destaca o volume." + }, + "pie": { + "label": "Pizza", + "description": "Proporção do total por categoria." + }, + "metric": { + "label": "Métrica", + "description": "Um único valor escalar." + }, + "table": { + "label": "Tabela", + "description": "Linhas agregadas." + }, + "list": { + "label": "Lista", + "description": "Linhas brutas, sem agregação." + }, + "region_map": { + "label": "Mapa de coordenadas", + "description": "Posicione marcadores em um mapa-múndi usando coordenadas lat/lon." + }, + "text": { + "label": "Texto", + "description": "Texto livre ou saída simples por linha." + } + }, + "dataSource": { + "title": "Quais dados?", + "dataset": "Conjunto de dados", + "noDatasetHint": "Escolha um conjunto de dados para habilitar condições e agrupamento." + }, + "widgetTitle": { + "label": "Título", + "placeholder": "Opcional — padrão é o tipo de gráfico" + }, + "dataset": { + "placeholder": "Selecione um conjunto de dados…", + "loading": "Carregando conjuntos de dados…" + }, + "filters": { + "title": "Incluir apenas eventos onde…", + "empty": "Sem condições — todos os eventos do intervalo de tempo são incluídos.", + "add": "Adicionar condição", + "remove": "Remover", + "field": "Campo", + "fieldPlaceholder": "ex.: host.name", + "operator": "Operador", + "value": "Valor", + "valuePlaceholder": "Valor", + "from": "De", + "to": "Até", + "noValue": "Nenhum valor necessário", + "listPlaceholder": "Valores separados por vírgula" + }, + "operators": { + "IS": "é", + "IS_NOT": "não é", + "IS_ONE_OF_TERMS": "é um de", + "IS_GREATER_THAN": "é maior que", + "IS_LESS_THAN_OR_EQUALS": "é menor ou igual a", + "IS_BETWEEN": "está entre", + "CONTAIN": "contém", + "DOES_NOT_CONTAIN": "não contém", + "START_WITH": "começa com", + "ENDS_WITH": "termina com", + "EXIST": "existe", + "DOES_NOT_EXIST": "não existe" + }, + "dimension": { + "title": "Agrupar por", + "field": "Campo", + "placeholder": "Escolha um campo para agrupar…" + }, + "table": { + "hint": "Mostra todos os campos dos registros. Adicione colunas para escolher alguns.", + "columnsTitle": "Colunas", + "allColumns": "Todas as colunas serão exibidas. Adicione campos para escolher colunas específicas.", + "addColumn": "Adicionar uma coluna…", + "removeColumn": "Remover coluna" + }, + "chartPreview": { + "title": "Pré-visualização do gráfico", + "noQuery": "Escolha um conjunto de dados para ver a pré-visualização.", + "error": "A consulta de pré-visualização falhou." + }, + "chartTypeChip": { + "label": "Gráfico:" + }, + "chartTypeModal": { + "title": "Escolha um tipo de gráfico", + "subtitle": "Escolha como visualizar os dados. Você pode alterar isso depois.", + "confirm": "Continuar", + "swapTitle": "Alterar tipo de gráfico", + "swapConfirm": "Aplicar" + }, + "saveVisualization": "Salvar widget", + "fieldSelect": { + "loading": "Carregando campos…", + "choose": "Escolha um campo…" + }, + "toast": { + "notReady": "Escolha um conjunto de dados e um campo para detalhar antes de salvar." + }, + "breakdown": { + "title": "Detalhar por", + "topValuesTable": "Tabela de valores principais", + "time": "Ao longo do tempo", + "field": "Valores mais frequentes", + "interval": "Tamanho do intervalo", + "intervalAuto": "Automático", + "limit": "Quantos", + "limitPlaceholder": "Padrão (50)", + "splitHint": "Opcional: uma linha por valor deste campo." + }, + "editFilters": "Edit filters" + }, + "grid": { + "empty": "Este painel ainda não tem widgets.", + "missingVisualization": "Widget indisponível", + "unknownVisualization": "Widget" + }, + "widget": { + "renderError": "Não foi possível renderizar este widget.", + "count": "Contagem", + "loading": "Carregando dados…", + "queryError": "Não foi possível carregar os dados do widget.", + "noData": "Sem dados para o intervalo de tempo selecionado.", + "regionMapEmpty": "Nenhum ponto com lat/lon válidos.", + "regionMapShapeHint": "O SQL deve retornar colunas de latitude e longitude (ou um array value [lat, lon, count]).", + "regionMapUnnamed": "(sem nome)", + "regionMapValue": "valor: {{value}}", + "editAriaLabel": "Editar widget", + "removeAriaLabel": "Remover widget", + "moveBack": "Mover para trás", + "moveForward": "Mover para frente", + "width": "Largura", + "height": "Altura", + "widthSmall": "1 col", + "widthMedium": "2 cols", + "widthLarge": "3 cols", + "heightNormal": "Normal", + "heightTall": "Alto", + "incompleteSpec": "Falta parte da pergunta deste widget." + }, + "form": { + "createTitle": "Novo painel", + "renameTitle": "Editar painel", + "name": "Nome", + "namePlaceholder": "ex.: Visão geral da rede", + "description": "Descrição", + "descriptionPlaceholder": "Opcional", + "cancel": "Cancelar", + "create": "Criar", + "save": "Salvar" + }, + "confirm": { + "deleteTitle": "Excluir painel", + "delete": "Excluir o painel \"{{name}}\"? Esta ação não pode ser desfeita.", + "deleteWidgetsTitle": "Excluir widgets", + "deleteWidgets_one": "Excluir este widget? Esta ação não pode ser desfeita.", + "deleteWidgets_other": "Excluir {{count}} widgets? Esta ação não pode ser desfeita.", + "dismissTitle": "Remover painel", + "dismiss": "Remover o painel padrão \"{{name}}\"? Você poderá criar um novo a partir dele depois com \"Novo\" → \"De uma existente\"." + }, + "page": { + "noSelection": "Escolha um painel na lista ou crie um para começar.", + "loading": "Carregando widgets…" + }, + "toast": { + "created": "Painel criado.", + "createFailed": "Não foi possível criar o painel.", + "updated": "Painel atualizado.", + "updateFailed": "Não foi possível atualizar o painel.", + "deleted": "Painel excluído.", + "deleteFailed": "Não foi possível excluir o painel.", + "layoutSaved": "Layout salvo.", + "layoutSaveFailed": "Não foi possível salvar o layout.", + "visualizationCreated": "Widget criado.", + "visualizationCreateFailed": "Não foi possível criar o widget.", + "visualizationUpdated": "Widget atualizado.", + "visualizationUpdateFailed": "Não foi possível atualizar o widget.", + "visualizationDeleted": "Widget excluído.", + "visualizationDeleteFailed": "Não foi possível excluir o widget.", + "filterCreated": "Filtro criado.", + "filterUpdated": "Filtro atualizado.", + "filterDeleted": "Filtro excluído.", + "filterCreateFailed": "Não foi possível criar o filtro.", + "filterUpdateFailed": "Não foi possível atualizar o filtro.", + "filterDeleteFailed": "Não foi possível excluir o filtro.", + "filtersSaved": "Filters saved.", + "filtersSaveFailed": "Could not save filters." + }, + "newDashboard": { + "title": "Novo painel", + "subtitle": "Crie um painel em branco. Você pode adicionar widgets depois de salvá-lo.", + "modeManual": "Criar manualmente", + "modeAi": "Usando IA", + "aiLocked": "Ative o SOC-AI e configure-o para usar isso.", + "aiDescriptionLabel": "O que este painel deve mostrar?", + "aiDescriptionPlaceholder": "ex. Logins com falha por país, últimos 7 dias", + "aiCreate": "Criar com IA", + "aiOpenerWithDetails": "Crie um painel chamado \"{{name}}\" mostrando: {{description}}" + }, + "newVisualization": { + "title": "Novo widget", + "subtitle": "Defina um gráfico reutilizável a partir de uma consulta SQL e de uma configuração de ECharts.", + "sqlQuery": "Consulta SQL", + "sqlQueryPlaceholder": "SELECT bucket, count(*) FROM logs GROUP BY bucket", + "sqlQueryHint": "Use os marcadores timeFilter, from e to (entre chaves duplas) para que o seletor de tempo seja aplicado na renderização.", + "config": "Configuração do gráfico (opção do ECharts, JSON)", + "configHint": "Deve ser um JSON válido. As linhas do SQL ficam expostas como `dataset.source` — conecte suas séries com `encode`.", + "configError": "JSON inválido: {{error}}" + }, + "visualizationList": { + "title": "Widgets", + "subtitle": "{{count}} widget(s) disponível(eis).", + "subtitleFiltered": "Exibindo {{shown}} de {{total}}.", + "create": "Nova", + "searchPlaceholder": "Pesquisar widgets…", + "loading": "Carregando widgets…", + "empty": "Ainda não há widgets.", + "emptyFiltered": "Nenhum widget corresponde aos filtros atuais.", + "delete": "Excluir", + "deleteTitle": "Excluir widget", + "confirmDelete": "Excluir o widget \"{{name}}\"? Esta ação não pode ser desfeita.", + "filters": { + "search": "Pesquisar", + "chartType": "Tipo de gráfico", + "allChartTypes": "Todos os tipos de gráfico", + "source": "Fonte", + "allSources": "Todas as fontes", + "createdAt": "Criada", + "modifiedAt": "Modificada", + "createdRangeTitle": "Intervalo personalizado — Criação", + "modifiedRangeTitle": "Intervalo personalizado — Modificação", + "pickRange": "Escolher um intervalo", + "datePresets": { + "all": "Todo o período", + "today": "Hoje", + "last7": "Últimos 7 dias", + "last30": "Últimos 30 dias", + "lastYear": "Último ano", + "custom": "Intervalo personalizado" + }, + "clear": "Limpar filtros" + }, + "col": { + "name": "Nome", + "chartType": "Tipo de gráfico", + "source": "Fonte", + "description": "Descrição", + "created": "Criada", + "modified": "Modificada" + } + }, + "tabs": { + "dashboards": "Painéis", + "visualizations": "Widgets", + "newDashboard": "Novo painel", + "unsetDefault": "Remover padrão", + "options": "Opções" + }, + "picker": { + "none": "Selecionar painel", + "search": "Buscar painéis…", + "new": "Novo painel", + "setDefault": "Definir como padrão", + "empty": "Sem painéis" + }, + "empty": { + "title": "Ainda não há painéis", + "body": "Crie seu primeiro painel para ver seus dados de segurança rapidamente.", + "cta": "Criar painel" + }, + "filters": { + "addTitle": "Adicionar filtro", + "editTitle": "Editar filtro", + "removeTitle": "Remover filtro", + "removeConfirm": "Remover o filtro \"{{label}}\"? Esta ação não pode ser desfeita.", + "remove": "Remover", + "editAria": "Editar filtro", + "removeAria": "Remover filtro", + "saving": "Salvando…", + "addChip": "Adicionar filtro", + "chooseValue": "Choose…", + "selected": "selected", + "loading": "Loading values…", + "searchPlaceholder": "Search values…", + "noValues": "No values available.", + "loadError": "Could not load values.", + "clear": "Clear", + "editorTitle": "Dashboard filters", + "editorHint": "Add dropdown chips that filter every widget on this dashboard.", + "emptyEditor": "No filter chips yet. Add one to get started.", + "cancel": "Cancel", + "save": "Save", + "field": { + "dataset": "Data set", + "field": "Field", + "chooseField": "Choose a field…", + "label": "Label", + "labelPlaceholder": "e.g. Host", + "placeholder": "Placeholder", + "placeholderPlaceholder": "e.g. Pick a host", + "multiple": "Multiple", + "searchable": "Searchable" + } + }, + "duplicate": { + "copyName": "{{name}} (cópia)" + } }, - "sessions": { - "title": "Sessões ativas", - "description": "Dispositivos atualmente conectados à sua conta.", - "loading": "Carregando sessões…", - "empty": "Nenhuma sessão ativa.", - "thisDevice": "Este dispositivo", - "unknownIp": "IP desconhecido", - "unknownDevice": "Dispositivo desconhecido", - "deviceLabel": "{{browser}} em {{os}}", - "signedIn": "Conectado {{time}}", - "revoke": "Revogar", - "revoking": "Revogando…", - "signOutOthers": "Encerrar todas as outras sessões", - "signingOut": "Encerrando…" + "settings": { + "title": "Configurações", + "license": "Licença", + "notifications": "Notificações", + "connectionKey": "Chave de conexão", + "dataRetention": "Retenção de dados", + "indices": "Índices", + "theme": "Tema", + "branding": "Marca", + "apiKeys": "Chaves de API", + "identityProviders": "Provedores de identidade", + "email": "Configuração de e-mail", + "dateFormat": "Formato de data", + "language": "Idioma", + "auditLogs": "Logs de auditoria", + "about": "Sobre", + "socAi": "SOC-AI", + "supportAccess": "Acesso de suporte", + "threatwinds": "Integração ThreatWinds" + }, + "topbar": { + "theme": { + "light": "Modo claro", + "dark": "Modo escuro" + }, + "manageLicense": "Gerenciar licença", + "profile": { + "profile": "Perfil", + "license": "Licença", + "logout": "Sair" + } }, - "tfa": { - "title": "Autenticação em duas etapas", - "description": "Adicione uma camada extra de segurança à sua conta.", - "loading": "Carregando…", - "methodTotp": "App autenticador", - "methodEmail": "Código por e-mail", - "onTitle": "A autenticação em duas etapas está ativada", - "method": "Método: {{method}}", - "configured": "Configurado", - "disable": "Desativar", - "disableTitle": "Desativar autenticação em duas etapas", - "disableDescription": "Digite sua senha atual para confirmar. Sua conta dependerá apenas da senha depois disso.", - "currentPasswordPlaceholder": "Senha atual", - "disableConfirm": "Desativar 2FA", - "disabling": "Desativando…", - "offTitle": "A autenticação em duas etapas está desativada", - "status": "Status:", - "notConfigured": "Não configurado", - "enable": "Ativar", - "chooseMethod": "Escolha um método", - "totpDesc": "Use Google Authenticator, 1Password, etc. Recomendado.", - "emailDesc": "Receba um código de 6 dígitos por e-mail ao entrar.", - "noEmailHint": "Adicione um e-mail ao seu perfil para usar o método por e-mail.", - "continue": "Continuar", - "starting": "Iniciando…", - "scanTitle": "Escaneie o código QR", - "scanDescription": "Escaneie com seu app autenticador e digite o código de 6 dígitos que ele mostra.", - "manualKey": "Ou digite esta chave manualmente:", - "checkEmailTitle": "Verifique seu e-mail", - "checkEmailDescription": "Enviamos um código de 6 dígitos para {{email}}. Digite-o abaixo.", - "resend": "Reenviar", - "verifyEnable": "Verificar e ativar", - "verifying": "Verificando…" + "notifications": { + "title": "Notificações", + "markAllRead": "Marcar todas como lidas", + "empty": "Você não tem notificações.", + "viewAll": "Ver todas", + "markRead": "Marcar como lida", + "markUnread": "Marcar como não lida", + "delete": "Excluir", + "subtitle": "{{total}} no total · {{unread}} não lidas", + "allCaughtUp": "Tudo em dia.", + "loadFailed": "Não foi possível carregar as notificações." }, - "actions": { - "cancel": "Cancelar" + "pagination": { + "perPage": "Por página", + "pageOf": "Página {{page}} de {{total}}", + "previous": "Anterior", + "next": "Próxima" }, - "toast": { - "profileUpdated": "Perfil atualizado", - "emailInUse": "Esse e-mail já está em uso", - "profileUpdateFailed": "Não foi possível atualizar o perfil", - "passwordsNoMatch": "As senhas não coincidem", - "passwordTooShort": "A senha deve ter pelo menos 8 caracteres", - "passwordChanged": "Senha alterada — as outras sessões foram encerradas", - "currentPasswordWrong": "A senha atual está incorreta", - "passwordChangeFailed": "Não foi possível alterar a senha", - "avatarTypeNotAllowed": "Tipo de imagem não permitido (use PNG, JPEG, WEBP ou GIF)", - "avatarTooLarge": "A imagem é muito grande (máx. 2MB)", - "avatarUpdated": "Avatar atualizado", - "avatarUploadFailed": "Não foi possível enviar o avatar", - "avatarRemoved": "Avatar removido", - "avatarRemoveFailed": "Não foi possível remover o avatar", - "sessionsLoadFailed": "Não foi possível carregar as sessões", - "sessionRevoked": "Sessão revogada", - "sessionRevokeFailed": "Não foi possível revogar a sessão", - "othersSignedOut": "As outras sessões foram encerradas", - "othersRevokeFailed": "Não foi possível revogar as sessões", - "tfaEmailCodeSent": "Enviamos um código de 6 dígitos para seu e-mail", - "tfaNewCodeSent": "Um novo código foi enviado", - "tfaWaitResend": "Aguarde um momento antes de pedir um novo código", - "tfaResendFailed": "Não foi possível reenviar o código", - "tfaEnterCode": "Digite o código de 6 dígitos", - "tfaEnabled": "Autenticação em duas etapas ativada", - "tfaEnterPassword": "Digite sua senha atual", - "tfaDisabled": "Autenticação em duas etapas desativada", - "tfaDisableFailed": "Não foi possível desativar o 2FA", - "tfaInvalidCode": "Código inválido ou expirado", - "tfaAlreadyEnabled": "O 2FA já está ativado", - "tfaTooManyRequests": "Muitas solicitações; tente novamente em instantes", - "tfaVerifyFailed": "Não foi possível verificar o código", - "genericError": "Algo deu errado", - "tfaMailUnavailable": "O segundo fator por e-mail precisa de um servidor de e-mail. Configure-o em Configurações → Configuração de e-mail." - } - }, - "home": { - "hero": { - "title": "O que você gostaria de saber a partir dos seus dados de segurança?", - "placeholder": "Pesquise o Scattered Spider, isso se aplica a nós?, já fomos atacados?, crie uma regra de detecção e mantenha-a ajustada.", - "send": "Enviar", - "suggestions": { - "threatHunt": "Caça a ameaças", - "observableTriage": "Triagem de observáveis", - "writeRule": "Escrever uma regra", - "systemStatus": "Status atual do sistema" - } + "license": { + "title": "Licença", + "subtitle": "Sua edição, recursos e arquivo de licença.", + "loading": "Carregando licença…", + "loadError": "Não foi possível carregar as informações da licença.", + "statusLabel": "Status", + "status": { + "community": "Community", + "active": "Ativa", + "expiring": "A expirar", + "expired": "Expirada" + }, + "edition": "Edição", + "enterprise": "Enterprise", + "community": "Community", + "editionLine": "Edição {{edition}}", + "datasourceLimit": "Limite de fontes de dados", + "unlimited": "Ilimitado", + "mssp": "MSSP / multi-tenant", + "enabled": "Ativado", + "licenseType": "Tipo de licença", + "instanceId": "ID da instância", + "enterpriseUnlocked": "Recursos Enterprise desbloqueados", + "validUntil": "Válida até", + "noExpiry": "Sem expiração", + "timeRemaining": "Tempo restante", + "expiredAgo": "Expirou há {{days}}d", + "daysShort": "{{days}}d", + "msspShort": "MSSP", + "communityEdition": "Edição Community", + "communityBlurb": "Gratuita e de código aberto. Envie uma licença Enterprise abaixo para desbloquear multi-tenancy, SSO, limites maiores de fontes de dados e conformidade avançada.", + "upgrade": "Atualizar para Enterprise", + "uploadTitle": "Enviar uma licença", + "uploadBlurb": "Instale ou substitua o arquivo LICENSE assinado. O servidor valida a assinatura e a expiração antes de aplicá-lo. Apenas admin.", + "installLicense": "Instalar licença", + "chooseFile": "Escolher arquivo", + "noFileSelected": "Nenhum arquivo selecionado", + "toast": { + "installed": "Licença instalada — edição {{edition}}.", + "adminRequired": "São necessários privilégios de administrador para enviar uma licença.", + "invalid": "Arquivo de licença inválido ou expirado.", + "installFailed": "Não foi possível instalar a licença." + }, + "ingestLimit": "Volume de ingestão", + "notMetered": "Sem medição", + "gbPerMonth": "{{gb}} GB/mês" + }, + "audit": { + "title": "Log de auditoria", + "subtitle": "Registro de cada ação relevante para a segurança.", + "totalEntries": "{{total}} entradas no total.", + "loadError": "Não foi possível carregar o log de auditoria", + "stats": { + "totalEntries": "Entradas totais", + "acrossAllTime": "De todo o período", + "successRate": "Taxa de sucesso", + "failuresOnPage_one": "{{count}} falha nesta página", + "failuresOnPage_other": "{{count}} falhas nesta página", + "topAction": "Ação principal", + "onPage": "{{count}} nesta página", + "uniqueActors": "Atores únicos", + "includingSystem": "Incluindo o sistema" + }, + "filters": { + "title": "Filtros", + "clear": "Limpar", + "last24h": "Últimas 24h", + "failuresOnly": "Apenas falhas", + "authEvents": "Eventos de autenticação", + "actionPrefix": "Prefixo da ação", + "actionPlaceholder": "ex. auth., user.update", + "status": "Status", + "any": "Qualquer", + "resourceType": "Tipo de recurso", + "resourceTypePlaceholder": "user, alert…", + "resourceId": "ID do recurso", + "user": "Usuário", + "userPlaceholder": "login…" + }, + "statusValue": { + "success": "Sucesso", + "failure": "Falha" + }, + "table": { + "timestamp": "Data e hora", + "actor": "Ator", + "action": "Ação", + "resource": "Recurso", + "status": "Status", + "ip": "IP", + "loading": "Carregando…", + "emptyTitle": "Nenhuma entrada corresponde a estes filtros.", + "emptyHint": "Tente limpar os filtros ou ampliar o intervalo de datas.", + "system": "sistema", + "view": "Ver" + }, + "drawer": { + "entry": "entrada #{{id}}", + "overview": "Visão geral", + "raw": "JSON bruto", + "error": "Erro", + "actor": "Ator", + "resource": "Recurso", + "ip": "IP", + "userAgent": "Agente de usuário", + "session": "Sessão", + "metadata": "Metadados", + "copy": "Copiar", + "copied": "Copiado", + "copyJson": "Copiar JSON" + } }, - "kpis": { - "alerts24h": "Alertas (24 h)", - "openIncidents": "Incidentes abertos", - "openIncidentsSub": "abertos no momento", - "highSeverity24h": "Severidade alta (24 h)", - "highSeveritySub": "de {{n}} alertas", - "activePlaybooks": "Playbooks ativos", - "activePlaybooksSub": "habilitados" + "team": { + "title": "Equipe", + "subtitle": "Gerencie os usuários e suas funções.", + "tabs": { + "members": "Membros", + "roles": "Funções e permissões" + }, + "toast": { + "rolesLoadFailed": "Não foi possível carregar as funções", + "userLoadFailed": "Não foi possível carregar o usuário", + "rolesUpdated": "Funções atualizadas", + "userReactivated": "Usuário reativado", + "userDeactivated": "Usuário desativado", + "tfaReset": "Autenticação em duas etapas redefinida", + "invitationSent": "Convite enviado", + "loginOrEmailInUse": "Esse login ou e-mail já está em uso", + "invalidRequest": "Solicitação inválida", + "noPermission": "Você não tem permissão para fazer isso", + "userNotFound": "Usuário não encontrado", + "operationFailed": "A operação falhou", + "emailInUse": "Esse e-mail já está em uso", + "roleCreated": "Função criada", + "roleUpdated": "Função atualizada", + "roleDeleted": "Função excluída", + "roleNameInUse": "Já existe uma função com esse identificador", + "roleImmutable": "Funções de sistema não podem ser modificadas", + "permissionsLoadFailed": "Não foi possível carregar as permissões", + "localUserCreated": "Usuário local criado" + }, + "members": { + "searchPlaceholder": "Pesquisar por nome ou e-mail…", + "invite": "Convidar usuário", + "colUser": "Usuário", + "colRoles": "Funções", + "col2fa": "2FA", + "colStatus": "Status", + "loading": "Carregando usuários…", + "loadFailed": "Não foi possível carregar os usuários.", + "retry": "Tentar novamente", + "noSearchMatch": "Nenhum usuário corresponde à sua busca.", + "none": "Ainda não há usuários.", + "noRole": "nenhuma", + "on": "Sim", + "off": "Não", + "countLabel_one": "{{count}} usuário · página {{page}} de {{pages}}", + "countLabel_other": "{{count}} usuários · página {{page}} de {{pages}}", + "federated": "SSO" + }, + "status": { + "inactive": "Inativo", + "pendingPassword": "Senha pendente", + "active": "Ativo", + "pending": "Convite pendente", + "suspended": "Suspenso" + }, + "drawer": { + "createdBy": "criado por {{actor}}", + "loading": "Carregando…", + "profileTitle": "Perfil", + "profileSubtitle": "Apenas o usuário pode editar isto, no seu próprio perfil.", + "name": "Nome", + "username": "Usuário", + "email": "E-mail", + "language": "Idioma", + "accountTitle": "Conta", + "status": "Status", + "statusActive": "Ativo", + "statusInactive": "Inativo", + "tfa": "2FA", + "tfaEnabled": "Ativada", + "tfaNotConfigured": "Não configurado", + "resetTfa": "Redefinir", + "resetTfaHint": "Desativa o 2FA deste usuário para que ele reconfigure no próximo login", + "resetTfaConfirmTitle": "Redefinir a autenticação em duas etapas?", + "resetTfaConfirmBody": "Isso desativa o 2FA de {{name}}. Ela entrará apenas com a senha e poderá configurá-lo novamente no perfil.", + "resetTfaConfirm": "Redefinir 2FA", + "pendingPasswordNote": "Ainda usa a senha temporária (convite não concluído).", + "lastModified": "Modificado {{time}}", + "rolesTitle": "Funções", + "rolesSubtitle": "As funções concedem permissões de módulo. Um usuário pode ter mais de uma.", + "noRoleWarning": "Nenhuma função atribuída — o usuário não terá acesso a nenhum módulo.", + "deactivate": "Desativar", + "reactivate": "Reativar", + "waitingInvite": "Aguardando o usuário aceitar o convite.", + "cancel": "Cancelar", + "saving": "Salvando…", + "saveRoles": "Salvar funções", + "created": "criado {{time}}", + "pendingNote": "O convite ainda não foi aceito.", + "federatedNote": "Entra através de um provedor de identidade." + }, + "invite": { + "title": "Convidar usuário", + "description": "A conta é criada inativa. O usuário recebe um e-mail para definir sua senha e ativá-la.", + "username": "Usuário", + "usernameHint": "Pelo menos 3 caracteres.", + "email": "E-mail", + "firstName": "Nome", + "lastName": "Sobrenome", + "roles": "Funções", + "cancel": "Cancelar", + "sending": "Enviando…", + "send": "Enviar convite", + "name": "Nome", + "emailHint": "É o endereço com o qual fará login.", + "localDescription": "A conta é criada com uma senha e ativada imediatamente. Nenhum e-mail é enviado.", + "modeInvite": "Convidar usuário", + "modeLocal": "Criar usuário local", + "passwordLabel": "Senha", + "passwordPlaceholder": "Defina uma senha forte", + "localUserNote": "Este usuário não receberá um e-mail e será ativado automaticamente.", + "createLocal": "Criar usuário", + "passwordRules": { + "length": "Pelo menos 8 caracteres", + "case": "Pelo menos uma letra maiúscula e uma minúscula", + "special": "Pelo menos um caractere especial" + }, + "emailInvalid": "Insira um endereço de e-mail válido" + }, + "rolePicker": { + "none": "Nenhuma função disponível." + }, + "roles": { + "loading": "Carregando funções…", + "loadFailed": "Não foi possível carregar as permissões das funções.", + "readonlyNote": "As funções e suas permissões são definidas pelo sistema e são somente leitura. Atribua-as aos usuários na aba Membros.", + "permissionsCount_one": "{{count}} permissão", + "permissionsCount_other": "{{count}} permissões", + "modulesCount_one": "{{count}} módulo", + "modulesCount_other": "{{count}} módulos", + "matrixTitle": "Matriz de permissões", + "matrixSubtitle": "O que cada função pode fazer, por módulo.", + "permission": "Permissão", + "systemNote": "As funções de sistema vêm com a plataforma e não podem ser editadas. As que você criar pertencem a este tenant.", + "newRole": "Nova função", + "edit": "Editar", + "delete": "Excluir", + "systemBadge": "Sistema", + "createTitle": "Nova função", + "editTitle": "Editar função", + "editorSubtitle": "Escolha o que esta função pode fazer. Um usuário pode ter mais de uma.", + "nameLabel": "Identificador", + "nameHint": "Usado no código e na API. Por exemplo, ROLE_AUDITOR.", + "displayNameLabel": "Nome exibido", + "descriptionLabel": "Descrição", + "permissionsLabel": "Permissões", + "selectedCount": "{{count}} selecionadas", + "toggleAll": "todas", + "loadingPermissions": "Carregando permissões…", + "save": "Salvar função", + "deleteConfirmTitle": "Excluir esta função?", + "deleteConfirmBody": "{{name}} será removida. Quem tiver apenas esta função ficará sem acesso aos módulos." + }, + "langDefault": "Padrão do sistema", + "relative": { + "justNow": "agora mesmo", + "minutesAgo": "há {{count}} min", + "hoursAgo": "há {{count}} h", + "daysAgo": "há {{count}} d" + }, + "roleNames": { + "ROLE_ADMIN": "Administrador", + "ROLE_USER": "Usuário" + }, + "roleDescriptions": { + "ROLE_ADMIN": "Acesso total a todos os recursos", + "ROLE_USER": "Usuário padrão com acesso de leitura a nível de módulo" + }, + "actions": { + "read": "Leitura", + "write": "Escrita", + "delete": "Exclusão" + }, + "resources": { + "adaudit": "Auditoria AD", + "alerts": "Alertas", + "audit": "Registro de auditoria", + "compliance": "Conformidade", + "config": "Configuração", + "dashboards": "Painéis", + "datasources": "Datasources", + "eventprocessing": "Processamento de eventos", + "idp": "Provedores de identidade", + "incidents": "Incidentes", + "integrations": "Integrações", + "loganalyzer": "Analisador de logs", + "opensearch": "OpenSearch", + "roles": "Funções", + "soar": "SOAR", + "users": "Usuários", + "notifications": "Notificações", + "socai": "SOC AI", + "tenant": "Tenants", + "threatintel": "Inteligência de ameaças" + } }, - "datasources": { - "title": "Fontes de dados", - "viewAll": "Ver tudo", - "ofTotal": "de {{n}}", - "datasources": "fontes de dados", - "sendingData": "enviando dados", - "totalEvents": "Total de eventos", - "noData": "Sem dados de ingestão nesta janela" + "apiKeys": { + "title": "Chaves de API", + "subtitle": "Tokens de acesso programático para a API do UTMStack.", + "new": "Nova chave de API", + "searchPlaceholder": "Pesquisar por nome ou IP permitido…", + "refresh": "Atualizar", + "loading": "Carregando chaves de API…", + "loadFailed": "Não foi possível carregar as chaves de API.", + "retry": "Tentar novamente", + "noSearchMatch": "Nenhuma chave de API corresponde à sua pesquisa.", + "empty": "Ainda não há chaves de API. Crie uma para começar.", + "anyIp": "Qualquer IP", + "never": "Nunca", + "count_one": "{{count}} chave · página {{page}} de {{pages}}", + "count_other": "{{count}} chaves · página {{page}} de {{pages}}", + "enterprise": { + "title": "As chaves de API são um recurso Enterprise", + "body": "Emita, restrinja e rotacione chaves de API para acesso programático à API do UTMStack. Esse recurso está disponível na edição Enterprise.", + "upgrade": "Atualizar para Enterprise", + "manageLicense": "Gerenciar sua licença" + }, + "col": { + "name": "Nome", + "allowedIps": "IPs permitidos", + "created": "Criada", + "lastRotated": "Última rotação", + "expires": "Expira", + "status": "Status", + "actions": "Ações" + }, + "status": { + "active": "Ativa", + "expiring": "Expirando", + "expired": "Expirada" + }, + "action": { + "rotate": "Rotacionar", + "edit": "Editar", + "delete": "Excluir" + }, + "dialog": { + "editTitle": "Editar chave de API", + "newTitle": "Nova chave de API", + "name": "Nome", + "namePlaceholder": "ci-pipeline", + "allowedIps": "IPs permitidos", + "allowedIpsHint": "Separados por vírgula. Deixe vazio para permitir qualquer IP.", + "expires": "Expira", + "expiresHint": "Deixe vazio para uma chave que nunca expira.", + "secretNote": "O token secreto é mostrado uma única vez, logo após a criação. Copie-o então — não pode ser recuperado depois (apenas rotacionado).", + "cancel": "Cancelar", + "saving": "Salvando…", + "saveChanges": "Salvar alterações", + "createKey": "Criar chave" + }, + "confirm": { + "deleteTitle": "Excluir chave de API", + "rotateTitle": "Rotacionar chave de API", + "deleteBody": "Excluir {{name}}? Qualquer cliente que a utilize perderá o acesso imediatamente. Isso não pode ser desfeito.", + "rotateBody": "Rotacionar {{name}}? Um novo segredo é emitido e o atual para de funcionar imediatamente. O novo token é mostrado uma única vez.", + "cancel": "Cancelar", + "working": "Processando…", + "delete": "Excluir", + "rotate": "Rotacionar" + }, + "reveal": { + "title": "Chave de API criada", + "note": "Copie este segredo agora — para {{name}}. Ele não será mostrado novamente. Se você perdê-lo, rotacione a chave.", + "copied": "Copiado", + "copy": "Copiar", + "done": "Concluído" + }, + "toast": { + "updated": "Chave de API atualizada", + "secretIssueFailed": "Chave criada, mas o segredo não pôde ser emitido. Use Rotacionar para obter um.", + "deleted": "Chave de API excluída" + }, + "error": { + "nameTaken": "Já existe uma chave de API com esse nome", + "enterpriseRequired": "As chaves de API exigem a edição Enterprise", + "notFound": "Chave de API não encontrada", + "invalidRequest": "Solicitação inválida", + "failed": "Falha na operação" + } }, - "span": { - "recent": "janela recente", - "days_one": "último {{count}} dia", - "days_other": "últimos {{count}} dias", - "hours": "últimas {{n}} h" + "idp": { + "title": "Provedores de identidade", + "subtitle": "Login único SAML 2.0 para sua organização.", + "add": "Adicionar provedor", + "enterprise": { + "title": "O SSO é um recurso Enterprise", + "body": "Conecte um provedor de identidade SAML 2.0 (Entra ID, Okta, Google Workspace…) para que sua equipe faça login com seu IdP. O login único está disponível na edição Enterprise.", + "upgrade": "Atualizar para Enterprise" + }, + "loading": "Carregando provedores de identidade…", + "loadFailed": "Não foi possível carregar os provedores de identidade.", + "retry": "Tentar novamente", + "empty": { + "title": "Nenhum provedor de identidade configurado", + "body": "Adicione um provedor SAML 2.0 para que sua equipe faça login com seu IdP corporativo." + }, + "card": { + "enable": "Ativar", + "disable": "Desativar", + "active": "Ativo", + "disabled": "Desativado", + "metadataUrl": "URL de metadados", + "spEntityId": "SP Entity ID", + "spAcsUrl": "SP ACS URL", + "loginUrl": "URL de login", + "copy": "Copiar", + "edit": "Editar", + "delete": "Excluir", + "jit": "Provisioning", + "jitOn": "creates accounts on first sign-in", + "sync": "Roles", + "syncOn": "re-applied on every sign-in" + }, + "form": { + "addTitle": "Adicionar provedor de identidade", + "editTitle": "Editar provedor de identidade", + "name": "Nome", + "nameHint": "Único. Usado na URL de SSO.", + "providerType": "Tipo de provedor", + "providerTypeHint": "Um rótulo, ex. azure, okta, google.", + "metadataUrl": "URL de metadados do IdP", + "spEntityId": "SP Entity ID", + "spAcsUrl": "SP ACS URL", + "certificate": "Certificado SP (PEM)", + "privateKey": "Chave privada SP (PEM)", + "privateKeyHintEdit": "Deixe vazio para manter a chave armazenada.", + "privateKeyHintCreate": "Obrigatória. Armazenada criptografada; não é exibida novamente.", + "privateKeyUnchanged": "•••••••• (inalterada)", + "active": "Ativo (mostrar na página de login)", + "cancel": "Cancelar", + "saving": "Salvando…", + "save": "Salvar alterações", + "create": "Criar provedor", + "issuer": "Issuer URL", + "issuerHint": "Discovery runs against this; the provider must serve /.well-known/openid-configuration under it.", + "clientId": "Client ID", + "redirectUrl": "Redirect URL", + "redirectUrlHint": "Register this exact URL with the provider.", + "host": "Host", + "port": "Port", + "startTls": "TLS", + "startTlsOn": "Use StartTLS", + "bindDn": "Bind DN", + "bindDnHint": "A service account that may search the directory.", + "baseDn": "Base DN", + "userFilter": "User filter", + "userFilterHint": "Must contain %s, where the address typed at login is placed.", + "emailAttribute": "Email attribute", + "nameAttribute": "Name attribute", + "groupAttribute": "Group attribute", + "provisioning": "Accounts and roles", + "provisioningHint": "What happens when someone the directory vouches for signs in.", + "jit": "Create the account on first sign-in", + "defaultRole": "Default role", + "defaultRoleHint": "Given when no group matches. Without one, an unmatched sign-in is refused.", + "noDefaultRole": "None", + "groupsAttribute": "Groups attribute", + "groupsAttributeHint": "Where the provider puts group membership.", + "syncRoles": "Re-apply roles on every sign-in", + "syncRolesHint": "Roles not in the mapping are removed, so a change in the directory reaches here. Without this, a demotion never arrives.", + "mappings": "Group to role", + "mappingsHint": "A directory group on the left, the role it grants on the right.", + "addMapping": "Add", + "noMappings": "No mappings. Everyone gets the default role.", + "groupPlaceholder": "SOC Analysts", + "pickRole": "Pick a role", + "secret.saml": "SP private key", + "secret.oidc": "Client secret", + "secret.ldap": "Bind password", + "secretHintCreate": "Stored encrypted and never shown again.", + "secretHintEdit": "Leave blank to keep the stored one.", + "secretUnchanged": "inalterado", + "errors": { + "required": "Este campo é obrigatório.", + "url": "Deve ser uma URL http(s) válida.", + "httpsUrl": "Deve ser uma URL https válida.", + "hostname": "Insira um host ou IP sem esquema (ex.: ldap.exemplo.com).", + "port": "A porta deve ser um número inteiro entre 0 e 65535.", + "pemCertificate": "Não parece um certificado PEM (falta -----BEGIN/END CERTIFICATE-----).", + "pemKey": "Não parece uma chave privada PEM (falta -----BEGIN/END PRIVATE KEY-----).", + "userFilterPlaceholder": "O filtro deve conter %s, onde é colocado o endereço de login.", + "userFilterUnbalanced": "Parênteses desbalanceados — a busca não retornará nada.", + "nameFormat": "Use letras, dígitos, pontos, hífens ou underscores (máx. 64). Ele aparece na URL de SSO, sem espaços.", + "redirectUrl": "Deve ser uma URL https válida ou uma URL http de loopback (localhost / 127.0.0.1 / [::1]).", + "entityId": "Deve ser uma URI válida, ex.: https://utmstack.example.com/sp." + } + }, + "delete": { + "title": "Excluir provedor de identidade", + "body": "Excluir {{name}}? Os usuários não poderão mais fazer login por ele. Isso não pode ser desfeito.", + "cancel": "Cancelar", + "deleting": "Excluindo…", + "confirm": "Excluir" + }, + "toast": { + "enabled": "Provedor ativado", + "disabled": "Provedor desativado", + "created": "Provedor de identidade criado", + "updated": "Provedor de identidade atualizado", + "deleted": "Provedor de identidade excluído", + "paidPlan": "O SSO SAML requer um plano pago", + "enterpriseRequired": "O SSO requer a edição Enterprise", + "notFound": "Provedor de identidade não encontrado", + "invalid": "Configuração inválida", + "failed": "A operação falhou" + }, + "providerType": { + "saml": "SAML 2.0", + "oidc": "OpenID Connect", + "ldap": "LDAP / Active Directory", + "comingSoon": "ainda não disponível" + } }, - "mitre": { - "title": "Principais técnicas MITRE ATT&CK", - "explore": "Explorar", - "empty": "Ainda não há alertas com técnica atribuída" + "userAuditor": { + "title": "Auditor de usuários", + "subtitle": "Contas do Active Directory observadas nos seus logs de segurança do Windows — descobertas a partir de eventos de criação, logon e exclusão.", + "export": "Exportar", + "accountsChip": "{{count}} contas", + "overview": { + "title": "Inventário de contas", + "active": "ativas", + "disabled": "desativadas", + "deleted": "excluídas", + "seen24h": "{{count}} vistas nas últimas 24 horas", + "byDomain": "Por domínio", + "grouped": "{{count}} agrupados", + "unassigned": "{{count}} sem atribuição" + }, + "views": { + "all": "Todas as contas", + "windows": "Windows", + "linux": "Linux", + "active": "Ativas", + "disabled": "Desativadas", + "deleted": "Excluídas", + "service": "Contas de serviço", + "stale": "Inativas (30d+)", + "o365": "O365", + "azure": "Azure", + "gcp": "GCP", + "aws": "AWS" + }, + "searchPlaceholder": "Pesquisar por nome de conta ou SID…", + "allTenants": "Todos os tenants", + "filters": { + "add": "Adicionar filtro", + "clearAll": "Limpar tudo", + "filterValues": "Filtrar valores…", + "loadingValues": "Carregando valores…", + "noValues": "Nenhum valor encontrado.", + "pickValue": "Escolha um valor para adicionar o filtro.", + "empty": "(vazio)", + "cancel": "Cancelar", + "addBtn": "Adicionar" + }, + "filterFields": { + "status": "Status do ciclo de vida" + }, + "ops": { + "is": "é" + }, + "refresh": "Atualizar", + "layout": { + "list": "Lista", + "cards": "Cartões" + }, + "list": { + "account": "Conta", + "identity": "Identidade", + "sid": "SID", + "status": "Status", + "lastLogon": "Último logon", + "lastSeen": "Visto por último", + "tenant": "Tenant", + "accountId": "ID da conta", + "identityGroup": "Grupo de identidade" + }, + "status": { + "active": "Ativa", + "disabled": "Desativada", + "deleted": "Excluída" + }, + "badge": { + "service": "serviço", + "stale": "inativa" + }, + "empty": "Nenhuma conta corresponde a esta visão.", + "loadError": "Não foi possível carregar as contas do AD.", + "retry": "Tentar novamente", + "card": { + "lastLogon": "Último logon" + }, + "pageInfo": "{{from}}–{{to}} de {{count}}", + "drawer": { + "tenantInline": "tenant {{id}}", + "serviceAccount": "conta de serviço", + "stale": "inativa 30d+", + "viewInLogs": "Ver eventos no Log Explorer", + "copySid": "Copiar SID", + "copyUid": "Copiar identidade", + "copied": "Copiado", + "identity": "Identidade", + "accountName": "Nome da conta", + "domain": "Domínio", + "hostname": "Hostname", + "sid": "SID", + "uidNumber": "UID", + "machineId": "ID da máquina", + "tenant": "Tenant", + "adStatus": "Status no AD", + "enabled": "Habilitada", + "disabled": "Desabilitada", + "lifecycle": "Ciclo de vida", + "created": "Conta criada", + "lastLogon": "Último logon", + "lastSeen": "Visto por último nos logs", + "deleted": "Conta excluída", + "noLifecycle": "Sem eventos de ciclo de vida.", + "aliasGroup": "Grupo de identidade", + "alias": { + "add": "Adicionar grupo de identidade", + "search": "Pesquisar grupos…", + "none": "Ainda não há grupos", + "new": "Novo grupo", + "unassign": "Remover do grupo", + "unassigned": "Sem grupo", + "newPlaceholder": "Nome do novo grupo (2–64 caracteres)", + "createAndAssign": "Criar e atribuir", + "nameTooShort": "O nome deve ter entre 2 e 64 caracteres", + "updated": "Grupo de identidade atualizado", + "updateFailed": "Não foi possível atualizar o grupo de identidade" + } + }, + "relative": { + "justNow": "agora mesmo", + "minutesAgo": "há {{count}}m", + "hoursAgo": "há {{count}}h", + "daysAgo": "há {{count}}d" + }, + "none": "—", + "allIdentities": "Todos os grupos de identidade", + "noneIdentity": "Sem grupo de identidade" + }, + "connectionKey": { + "title": "Chave de conexão", + "subtitle1": "A chave que os agentes apresentam ao se registrar nesta instância.", + "subtitleEmphasis": "É usada apenas para a instalação de agentes", + "subtitle2": "— não para coletores, integrações ou a API. É gerenciada pelo agent-manager.", + "status": { + "label": "Status", + "loading": "Carregando…", + "unavailable": "Agent-manager indisponível", + "active": "Ativa", + "unavailableHint": "Não foi possível contatar o agent-manager para ler a chave.", + "activeHint": "Os agentes podem se registrar com esta chave." + }, + "token": { + "title": "Chave de conexão", + "subtitle": "Trate este valor como uma credencial. Rotacioná-la emite uma nova chave para futuras instalações de agentes — os agentes já registrados continuam funcionando.", + "loadFailedTitle": "Não foi possível carregar a chave de conexão", + "unavailableTitle": "Chave de conexão indisponível", + "loadFailedHint": "A chave é gerenciada pelo agent-manager, que não respondeu. Tente novamente em instantes.", + "retry": "Tentar novamente", + "show": "Mostrar chave", + "hide": "Ocultar chave", + "copy": "Copiar", + "copied": "Copiado", + "regenerate": "Regenerar chave de conexão", + "confirmTitle": "Regenerar a chave?", + "confirmBody": "As novas instalações de agentes precisarão da nova chave. Os agentes já registrados continuam funcionando. Não há como desfazer.", + "regenerating": "Regenerando…", + "confirmYes": "Sim, regenerar", + "cancel": "Cancelar" + }, + "security": { + "title": "Recomendações de segurança", + "subtitle": "Boas práticas para proteger esta credencial.", + "rotateTitle": "Rotacione a cada 90 dias", + "rotateBody": "Agende uma rotação recorrente. O UTMStack pode enviar um lembrete por e-mail quando a chave tiver mais de 90 dias.", + "rotateAction": "Configurar lembrete", + "secretTitle": "Armazene como segredo", + "secretBody": "Não faça commit no controle de versão. Use seu gerenciador de segredos (Vault, AWS SM, etc.) e injete-a no momento da instalação.", + "auditTitle": "Audite quem a obteve", + "auditBody": "Cada obtenção e rotação é registrada no log de auditoria da aplicação.", + "auditAction": "Ver log de auditoria" + }, + "toast": { + "loadFailed": "Não foi possível carregar a chave de conexão", + "rotated": "Chave de conexão rotacionada", + "rotateFailed": "Não foi possível rotacionar a chave de conexão", + "copyFailed": "Não foi possível copiar" + } }, - "assets": { - "title": "Ativos mais visados", - "viewAll": "Ver tudo", - "asset": "Ativo", - "alerts": "Alertas", - "empty": "Nenhum ativo visado nos alertas recentes" + "dataRetention": { + "title": "Retenção de dados", + "subtitle": "How long each dataset is kept, and when its records stop costing local disk.", + "loading": "Carregando…", + "loadFailed": "Could not read the store.", + "retry": "Tentar novamente", + "datasets": { + "logs": "Logs", + "alerts": "Alerts", + "statistics": "Ingestion statistics" + }, + "holding": "{{documents}} records · {{size}}", + "since": "since {{date}}", + "diskUsed": "Disk {{pct}}% used", + "keep": "Delete after", + "keepHint": "A record is deleted this many days after it happened, wherever it is stored by then.", + "cold": "Move to cold storage after", + "coldHint": "Older records move to object storage and stay queryable. 0 keeps everything on local disk.", + "coldUnavailable": "Set up cold storage below to move older records off local disk.", + "coldBeforeDelete": "Records have to move before they are deleted: use fewer days than the lifetime, or 0.", + "tieredNote": "This dataset moves records to cold storage. Going back to local-only needs the table rebuilt, so it cannot be turned off here.", + "days": "dias", + "save": "Salvar", + "saving": "Salvando…", + "toast": { + "saved": "Retention saved", + "noPermission": "You do not have permission to change retention", + "saveFailed": "Could not save the retention" + }, + "coldStorage": { + "title": "Cold storage", + "hint": "An object store the event store treats as a second, slower disk. Older records move there and are still queried from the same place — it is not an archive and nothing has to be restored.", + "active": "In use", + "inactive": "Not set up", + "writtenNotReady": "The bucket is configured but the store has not picked it up. Check that the deployment shares the store's configuration directory.", + "endpoint": "Bucket URL", + "accessKey": "Access key", + "secretKey": "Secret key", + "bucketLocked": "The credentials can be changed at any time. The bucket cannot, once records live in it: the parts already moved carry it.", + "enable": "Enable cold storage", + "update": "Update credentials", + "toast": { + "saved": "Cold storage configured", + "failed": "Could not configure cold storage" + }, + "kind": "Tipo", + "kind_s3": "Armazenamento de objetos compatível com S3", + "kind_local": "Pasta local ou NFS", + "kind_azure": "Azure Blob Storage", + "accountUrl": "URL da conta de armazenamento", + "container": "Contêiner", + "accountName": "Nome da conta", + "accountKey": "Chave da conta", + "useRole": "Usar a função IAM do servidor em vez de chaves", + "s3Hint": "Funciona com AWS S3 e qualquer armazenamento compatível com S3: MinIO, Ceph, Wasabi, Cloudflare R2 ou Google Cloud Storage (endpoint https://storage.googleapis.com// com chaves HMAC).", + "localHint": "Os registros vão para a pasta montada em /mnt/utmstack-cold dentro do armazenamento de eventos: um diretório comum na pasta de dados, ou um compartilhamento NFS montado no host sobre /clickhouse/cold antes de iniciar o stack. Não exige credenciais.", + "changeWarning": "Records already moved to the current destination are not migrated. They stay there and stop being readable from here until the old destination is copied across by hand." + }, + "forbidden": { + "title": "Esta página é da plataforma", + "body": "A retenção se aplica às tabelas que todos os tenants compartilham, então só um administrador da plataforma pode lê-la ou alterá-la." + } }, - "compliance": { - "title": "Pontuação de conformidade", - "reports": "Relatórios", - "empty": "Nenhum relatório de conformidade gerado ainda" + "languageSettings": { + "title": "Idioma da plataforma", + "subtitle": "Idioma padrão para as telas de pré-login, e-mails do sistema e novos usuários. Cada usuário ainda pode escolher o seu no perfil.", + "label": "Idioma padrão", + "hint": "Usado quando um usuário não escolheu o próprio idioma.", + "save": "Salvar", + "saving": "Salvando…", + "saved": "Idioma da plataforma atualizado", + "loadError": "Não foi possível carregar a configuração de idioma", + "saveError": "Não foi possível salvar a configuração de idioma" + }, + "branding": { + "title": "Marca", + "subtitle": "Personalize o UTMStack com a identidade da sua organização — aplicado em tudo: tela de login, menu lateral, e-mails e relatórios.", + "enterpriseRequired": "O white-label é um recurso Enterprise.", + "manageLicense": "Gerenciar licença", + "enable": { + "title": "White-label", + "description": "Substitua a marca UTMStack pela sua em toda a plataforma.", + "label": "Ativar white-label" + }, + "identity": { + "title": "Identidade", + "productName": "Nome do produto", + "productNameHint": "Exibido na barra de título, menu lateral e e-mails.", + "accent": "Cor de destaque", + "accentHint": "Cor primária de botões, links e estados ativos.", + "custom": "Cor personalizada" + }, + "logos": { + "title": "Logos", + "hint": "PNG, SVG, WEBP, JPG ou ICO. Até 5 MB.", + "logo": "Logo (claro)", + "logoDark": "Logo (escuro)", + "favicon": "Favicon" + }, + "reports": { + "title": "Recursos de relatório", + "hint": "Incorporados nos relatórios PDF gerados.", + "reportLogo": "Logo do relatório", + "reportCover": "Capa do relatório" + }, + "asset": { + "upload": "Enviar", + "replace": "Substituir" + }, + "save": "Salvar alterações", + "saving": "Salvando…", + "saved": "Marca atualizada", + "saveError": "Não foi possível salvar a marca", + "uploaded": "Imagem enviada", + "uploadError": "Não foi possível enviar a imagem", + "loadError": "Não foi possível carregar a marca", + "enterprise": { + "title": "A marca branca é um recurso Enterprise", + "body": "Substitua o nome do produto, o logotipo e a capa dos relatórios pelos seus, para que o painel e tudo o que ele gera levem a sua marca e não a da UTMStack.", + "upgrade": "Atualizar para Enterprise" + }, + "restore": "Restaurar os padrões da UTMStack", + "restored": "Marca restaurada aos padrões da UTMStack" + }, + "emailConfig": { + "title": "Configuração de e-mail", + "subtitle": "Servidor SMTP usado para enviar notificações de alertas, relatórios e e-mails de conta.", + "server": { + "title": "Servidor SMTP", + "host": "Host", + "hostHint": "Nome do servidor SMTP.", + "port": "Porta", + "encryption": "Criptografia", + "username": "Usuário", + "password": "Senha", + "passwordSetHint": "Há uma senha salva. Deixe em branco para mantê-la ou digite uma nova para alterá-la." + }, + "encryptionOpt": { + "TLS": "TLS", + "SSL": "SSL", + "NONE": "Nenhuma" + }, + "sender": { + "title": "Remetente", + "from": "Endereço de origem", + "fromHint": "Endereço a partir do qual os e-mails são enviados.", + "organization": "Nome da organização", + "organizationHint": "Exibido nos e-mails de notificação de alertas e incidentes.", + "baseUrl": "URL base", + "baseUrlHint": "URL pública desta instância, usada nos links dos e-mails." + }, + "test": { + "button": "Enviar teste", + "sending": "Enviando…", + "sentTo": "Um e-mail de teste será enviado para {{email}}.", + "success": "E-mail de teste enviado para {{email}}", + "fail": "Não foi possível enviar o e-mail de teste", + "fromRequired": "Defina um endereço de origem antes de testar" + }, + "save": "Salvar alterações", + "saving": "Salvando…", + "saved": "Configuração de e-mail salva", + "saveError": "Não foi possível salvar a configuração", + "loadError": "Não foi possível carregar a configuração", + "recipients": { + "alertsTitle": "Destinatários de alertas", + "incidentsTitle": "Destinatários de incidentes", + "to": "Para", + "cc": "CC", + "alertsHelper": "Endereços avisados quando novos alertas são gerados. Se deixar vazio, os alertas não são enviados por email.", + "incidentsHelper": "Endereços avisados quando um incidente é criado. Se deixar vazio, os incidentes não são enviados por email.", + "add": "Adicionar" + } }, - "health": { - "title": "Integridade do sistema", - "details": "Detalhes", - "services": { - "backend": "API do backend", - "opensearch": "Cluster do OpenSearch", - "socai": "Motor SOC-AI" - }, - "detail": { - "noClusterInfo": "sem informações do cluster", - "disabled": "desabilitado", - "tools": "{{n}} ferramentas", - "unreachable": "inacessível", - "pending": "…" - } - } - }, - "nav": { - "home": "Início", - "dashboards": "Painéis", - "dashboardList": "Lista de painéis", - "visualizationList": "Widgets", - "newDashboard": "Novo painel", - "newVisualization": "Novo widget", - "threatManagement": "Gestão de ameaças", - "alerts": "Alertas", - "incidents": "Incidentes", - "adversaryView": "Visão de adversários", - "soar": "SOAR", - "flows": "Fluxos", - "executionHistory": "Histórico de execuções", - "interactiveConsole": "Console interativo", - "logExplorer": "Explorador de logs", - "userAuditor": "Auditor de usuários", - "threatIntelligence": "Inteligência de ameaças", - "threat-intel": { - "indicators": "Indicadores", - "analyzt": "Analista de IA", - "triage": "Triagem", - "report": "Relatório" + "dateFormat": { + "title": "Data e hora", + "subtitle": "Como os timestamps são exibidos em toda a plataforma. Os logs são sempre armazenados em UTC.", + "timezone": { + "title": "Fuso horário", + "hint": "Os timestamps são exibidos neste fuso horário. Os dados são armazenados em UTC.", + "system": "Padrão do navegador", + "now": "Agora: {{value}}" + }, + "format": { + "title": "Formato de data", + "hint": "Estilo usado para datas e horas." + }, + "styles": { + "short": "Curto", + "medium": "Médio", + "long": "Longo", + "full": "Completo" + }, + "save": "Salvar alterações", + "saving": "Salvando…", + "saved": "Configurações de data salvas", + "saveError": "Não foi possível salvar as configurações", + "loadError": "Não foi possível carregar as configurações" + }, + "about": { + "title": "Sobre esta instância", + "subtitle": "Versão, licença e saúde do sistema deste deployment do UTMStack.", + "loading": "Carregando informações da instância…", + "edition": { + "enterprise": "Enterprise", + "community": "Community" + }, + "fields": { + "hostname": "Servidor", + "instanceId": "ID da instância", + "noInstanceMeta": "Nenhum metadado da instância disponível." + }, + "license": { + "title": "Licença", + "enterpriseMssp": "Enterprise · MSSP", + "datasources": "Datasources", + "communityLimited": "Limite Community", + "unlimited": "Ilimitado", + "expires": "Expira", + "managedNote": "Edição, limites de datasources e upload de licença são gerenciados na página de Licença.", + "view": "Ver licença", + "ingest": "Volume de ingestão", + "notMetered": "Sem medição", + "gbPerMonth": "{{gb}} GB/mês" + }, + "services": { + "backend": { + "name": "Backend API", + "desc": "Gateway REST, autenticação e orquestração de módulos." + }, + "opensearch": { + "name": "OpenSearch", + "desc": "Armazenamento de logs e eventos.", + "detail": "{{nodes}} nós · {{shards}} shards" + }, + "unreachable": "Inacessível" + }, + "status": { + "up": "Saudável", + "degraded": "Degradado", + "down": "Fora do ar", + "unknown": "Desconhecido" + }, + "health": { + "title": "Saúde do sistema", + "allHealthy": "Todos os serviços saudáveis. Atualize para verificar.", + "issues_one": "{{count}} serviço precisa de atenção.", + "issues_other": "{{count}} serviços precisam de atenção.", + "refresh": "Atualizar" + }, + "usage": { + "title": "Fontes de dados", + "subtitle": "Fontes de dados configuradas nesta instalação.", + "ofUnlimited": "de ilimitado", + "ofLimit": "de {{limit}}", + "overLimit": "Acima do limite licenciado — os dados além do limite estão em risco.", + "configured": "configuradas" + }, + "support": { + "title": "Suporte", + "docs": "Documentação", + "repo": "Repositório no GitHub", + "issues": "Relatar um problema", + "website": "utmstack.com" + }, + "legal": { + "title": "Legal", + "license": "Licença", + "security": "Divulgação de segurança", + "copyright": "© {{year}} UTMStack. Todos os direitos reservados." + } }, - "compliance": "Conformidade", - "configure": "Configurar", - "dataSources": "Fontes de dados", - "integrations": "Integrações", - "alertingRules": "Regras de alerta", - "dataProcessing": "Processamento de dados", - "team": "Equipe", - "settings": "Configurações", - "back": "Voltar", - "parsingFilters": "Pipelines", - "regexPatterns": "Expressões regulares", - "taggingRules": "Regras de Marcação", - "overview": "Visão geral", - "tenants": "Tenants", - "openMenu": "Abrir menu", - "closeMenu": "Fechar menu", - "liveOps": "Operações ao vivo" - }, - "dashboards": { - "title": "Painéis", - "subtitle": "Navegue e edite painéis interativos.", - "list": { - "title": "Painéis", - "create": "Novo", - "searchPlaceholder": "Pesquisar painéis…", - "loading": "Carregando painéis…", - "empty": "Ainda não há painéis.", - "rename": "Renomear", - "delete": "Excluir" + "logExplorer": { + "title": "Explorador de logs", + "eventsIn": "eventos em", + "searching": "Buscando…", + "query": { + "allDataTypes": "Todos os tipos de dados", + "dataTypes": "Tipos de dados", + "exportCsv": "Exportar CSV", + "filterDataTypes": "Filtrar tipos de dados…", + "noDataTypes": "Sem tipos de dados", + "noDataTypesMatch": "Nenhum tipo de dados corresponde", + "noTextSearch": "Esta origem não tem campo de texto completo — filtre por campo", + "refresh": "Atualizar", + "run": "Executar", + "search": "Pesquisar", + "searchPlaceholder": "Buscar em todos os campos…" + }, + "time": { + "15m": "Últimos 15 minutos", + "1h": "Última hora", + "6h": "Últimas 6 horas", + "24h": "Últimas 24 horas", + "7d": "Últimos 7 dias", + "30d": "Últimos 30 dias" + }, + "ops": { + "is": "é", + "isNot": "não é", + "contains": "contém", + "exists": "existe", + "between": "entre", + "search": "busca", + "isOneOf": "é um de", + "isNotOneOf": "não é nenhum de", + "doesNotContain": "no contiene", + "startsWith": "empieza con", + "doesNotStartWith": "no empieza con", + "endsWith": "termina con", + "doesNotEndWith": "no termina con", + "doesNotExist": "no existe", + "notBetween": "no está entre", + "greaterThan": "es mayor que", + "greaterThanOrEquals": "es mayor o igual que", + "lessThan": "es menor que", + "lessThanOrEquals": "es menor o igual que" + }, + "filters": { + "label": "Filtros", + "clearAll": "Limpar tudo" + }, + "fields": { + "title": "Campos", + "filterPlaceholder": "Filtrar campos…", + "none": "Sem campos", + "selected": "Campos selecionados", + "available": "Campos disponíveis", + "topValues_one": "Top {{count}} valor", + "topValues_other": "Top {{count}} valores", + "loading": "Carregando…", + "noValues": "Sem valores", + "addColumn": "Adicionar como coluna", + "removeColumn": "Remover coluna da tabela", + "filterFor": "Filtrar pelo valor", + "filterOut": "Excluir o valor", + "empty": "(vazio)" + }, + "results": { + "dataTypesFailed": "Não foi possível carregar os tipos de dados.", + "endOfResults": "Todos os {{count}} eventos carregados", + "loadingMore": "Carregando mais…", + "message": "Mensagem", + "none": "Nenhum log corresponde a esta consulta.", + "removeColumn": "Remover {{field}}", + "retry": "Tentar novamente", + "searchFailed": "A busca falhou.", + "searching": "Buscando…", + "source": "Origem", + "time": "Hora", + "scope": "Pesquisado em {{dataset}} · {{dataType}}.", + "searchAllDataTypes": "Pesquisar todos os tipos" + }, + "detail": { + "fieldsCount_one": "{{count}} campo", + "fieldsCount_other": "{{count}} campos", + "copyJson": "Copiar JSON", + "copied": "Documento copiado", + "parsedFields": "Campos analisados", + "json": "JSON", + "filterFor": "Filtrar por", + "filterOut": "Excluir", + "surrounding": "Eventos ao redor", + "surroundingHint": "Mostrar eventos ±15 min ao redor deste, da mesma fonte" + }, + "view": { + "table": "Tabela", + "chart": "Gráfico" + }, + "chart": { + "aggregateOn": "Agregar por", + "per": "a cada", + "topValues": "— top 20 valores", + "building": "Construindo gráfico…", + "failed": "Não foi possível construir o gráfico para este campo.", + "noData": "Sem dados para o gráfico." + }, + "intervals": { + "minute": "Minuto", + "hour": "Hora", + "day": "Dia", + "week": "Semana", + "month": "Mês", + "quarter": "Trimestre", + "year": "Ano" + }, + "toast": { + "exportFailed": "A exportação falhou" + }, + "builder": { + "add": "Adicionar filtro", + "filterValues": "Filtrar valores…", + "loadingValues": "Carregando valores…", + "noValues": "Sem valores.", + "cancel": "Cancelar", + "confirm": "Adicionar", + "pickValue": "Pick a value to add the filter." + }, + "related": { + "nLogs_one": "{{count}} log", + "nLogs_other": "{{count}} logs", + "truncated": "Mostrando os primeiros {{count}} logs relacionados (o conjunto completo é maior)." + }, + "saved": { + "title": "Salvas", + "empty": "Ainda não há buscas salvas", + "saveCurrent": "Salvar busca atual", + "save": "Salvar", + "namePlaceholder": "Nome da busca", + "delete": "Excluir", + "saved": "Salva “{{name}}”", + "loading": "Carregando…", + "loadFailed": "Não foi possível carregar as buscas salvas", + "saveFailed": "Não foi possível salvar a busca", + "deleteFailed": "Não foi possível excluir a busca", + "unreadable": "Não foi possível ler essa busca salva" + } }, - "actions": { - "edit": "Editar", - "editWithAi": "Editar com IA" + "integrations": { + "title": "Integrações", + "searchPlaceholder": "Pesquisar integrações…", + "noMatch": "Nenhuma integração corresponde.", + "browseMarketplace": "Explorar marketplace", + "loading": "Carregando integrações…", + "addCustom": { + "title": "Adicionar integração personalizada", + "description": "Criar uma nova fonte personalizada", + "cta": "Criar" + }, + "tabs": { + "all": "Todas", + "agents": "Agentes", + "collectors": "Coletores", + "cloud": "Cloud", + "custom": "Personalizada" + }, + "kind": { + "agents & syslog": "Agente", + "device": "Coletor", + "antivirus": "Coletor", + "other": "Coletor", + "custom": "Personalizada", + "cloud": "Cloud", + "utmstack modules": "Coletor" + }, + "status": { + "configured": "Configurada", + "available": "Disponível" + }, + "card": { + "manage": "Gerenciar →", + "setup": "Configurar →", + "eventsPerSec": "{{rate}} e/s", + "enabled": "Ativado", + "setupShort": "Configurar" + }, + "drawer": { + "manage": "Gerenciar", + "openDashboard": "Abrir painel", + "viewEvents": "Ver eventos", + "documentation": "Documentação", + "getInstallCmd": "Obter comando de instalação", + "setupCollector": "Configurar coletor", + "connect": "Conectar", + "configureCustom": "Configurar fonte personalizada", + "eventsRate": "{{rate}} eventos/s · {{count}} em 24h", + "manageRules": "Regras", + "manageFilters": "Filtros" + }, + "setup": { + "agent": { + "howItWorksTitle": "Como funciona", + "howItWorksBody": "O agente {{name}} é um pequeno daemon que executa no host e encaminha eventos locais para o UTMStack através de uma conexão TLS autenticada. Ele se atualiza automaticamente e relata sua saúde.", + "installTitle": "Instalar em {{name}}", + "installHint": "Execute este comando em cada host {{name}} que deseje monitorar. O token já codifica seu workspace atual.", + "afterTitle": "O que você verá após a instalação", + "after1": "O host aparece em Fontes de dados dentro de ~60 segundos após o início do agente.", + "after2": "A telemetria começa a fluir para o Log Explorer, limitada ao seu workspace.", + "after3": "O agente auto-relata CPU / memória / saúde do disco para o UTMStack.", + "actionLabel": "Ação", + "platformLabel": "Plataforma", + "optionsLabel": "Opções", + "skipCertValidation": "Não validar o certificado TLS (servidor autoassinado)", + "noRemoteControl": "Desativar a execução remota de comandos neste host", + "loadingToken": "Carregando token…", + "actions": { + "install": "Instalar", + "uninstall": "Desinstalar" + }, + "prereqTitle": "Requisitos de pré-instalação", + "prereqBody": "O agente UTMStack se comunica com o servidor pelas portas abaixo. Certifique-se de que estejam abertas entre o host e o UTMStack antes de instalar:", + "sensitiveWarning": "O comando abaixo contém um token de registro sensível — não o compartilhe.", + "uninstall": { + "title": "Desinstalar o agente", + "body": "Execute este comando no host para parar e remover o agente UTMStack e seus serviços. Utiliza a plataforma selecionada acima." + }, + "macCompat": "Requer macOS 11 (Big Sur) ou superior em Apple Silicon (M1/M2/M3 ou mais recente). Macs com Intel não são suportados." + }, + "collector": { + "howItWorksTitle": "Como funciona", + "howItWorksBody": "{{name}} não executa um agente do UTMStack. Em vez disso, você instala o coletor do UTMStack em algum lugar da rede que tanto seu dispositivo {{name}} quanto o UTMStack possam acessar. {{name}} envia syslog para o coletor, o coletor analisa, normaliza e encaminha eventos para o UTMStack.", + "step1Title": "1 · Instalar o coletor do UTMStack", + "step1Hint": "Execute em um host Linux com acesso de rede do dispositivo {{name}}.", + "step2Title": "2 · Configurar {{name}} para enviar syslog", + "step2Hint": "No dispositivo {{name}}, aponte o encaminhamento de syslog para o endereço do coletor em {{port}}.", + "vendorDocs": "Ver instruções específicas do fornecedor", + "step3Title": "3 · Verificar", + "step3Body": "Dentro de alguns minutos você deve ver eventos de {{name}} em source: {{source}} no Log Explorer, e uma nova entrada em Fontes de dados.", + "forwarder": { + "intro": { + "title": "Como funciona", + "body": "Os registros fluem de {{source}} para o UTMStack Collector, que os transmite com segurança ao UTMStack para correlação e alertas. Nada é instalado em {{source}} — apenas o Collector precisa ser executado em um host na sua rede." + }, + "diagram": { + "sourceSub": "seus registros", + "forwarder": "Collector", + "forwarderSub": "escuta na porta {{port}}", + "utmstack": "UTMStack", + "utmstackSub": "alertas e correlação", + "flow1": "registros", + "flow2": "seguro" + }, + "noInstall": "Nada é instalado em {{source}} — você apenas redireciona seus registros para o Collector.", + "install": { + "title": "Instalar o UTMStack Collector", + "body": "O Collector é um serviço Linux que recebe registros dos seus dispositivos e os envia ao UTMStack. Um único Collector gerencia múltiplas integrações ao mesmo tempo.", + "reuse": "Já tem um Collector em execução? Pule esta etapa — aponte {{source}} para o existente usando o host e a porta abaixo." + }, + "tls": { + "title": "Opcional — Habilitar criptografia TLS", + "intro": "Por padrão o listener aceita TCP/UDP simples. Para criptografar o tráfego syslog em trânsito, carregue os certificados primeiro e depois reative o listener com o protocolo tls.", + "step1": "1 · Carregar seu certificado e chave (uma vez por Collector)", + "step1Note": "Um certificado CA opcional pode ser adicionado como terceiro argumento. Se omitido, o certificado folha é usado como CA.", + "step2": "2 · Reativar o listener com TLS" + }, + "httpsCerts": { + "title": "Carregue o certificado TLS no Collector", + "body": "Esta integração usa um listener HTTPS na porta {{port}}, então o Collector precisa de um certificado e uma chave carregados antes de habilitá-la:" + }, + "uninstall": { + "title": "Opcional — Desinstalar o Collector", + "body": "Execute este comando no host onde o Collector está instalado para parar o serviço e remover todos os seus arquivos." + }, + "instanceHeader": { + "title": "Cabeçalho de autorização", + "body": "Inclua este cabeçalho Authorization em cada requisição enviada à instância. O segredo da chave de API é revelado apenas uma vez ao gerá-la — copie-o naquele momento e cole no lugar do marcador abaixo.", + "tabSimple": "Simples", + "tabBatch": "Lote" + }, + "manualCommand": { + "title": "Optional — Enable via the command line instead", + "intro": "Prefer the terminal? SSH into the Collector host and run the command below — it matches whatever protocol and port you have selected above.", + "certStep": "1 · Load your certificate and key (once per Collector)", + "enableStep": "2 · Enable the integration" + } + }, + "cisco": { + "source": "Cisco ASA", + "step1": { + "title": "Ativar o listener Cisco ASA no Collector", + "body": "No host onde o Collector está instalado, execute este comando para abrir o listener de registros Cisco ASA:", + "note": "Para usar TCP em vez de UDP, substitua udp por tcp no comando acima." + }, + "step2": { + "title": "Configurar o Cisco ASA para encaminhar registros", + "body": "No seu Cisco ASA, habilite o syslog e aponte-o para o host do Collector na porta {{port}}. Execute estes comandos no modo EXEC privilegiado (substitua pelo nome da sua interface interna ou de gerenciamento):" + } + }, + "ciscoSwitch": { + "source": "Cisco Switch", + "step1": { + "title": "Ativar o listener Cisco Switch no Collector", + "body": "No host onde o Collector está instalado, execute este comando para abrir o listener de registros Cisco Switch:", + "note": "Para usar TCP em vez de UDP, substitua udp por tcp no comando acima." + }, + "step2": { + "title": "Configurar o switch para encaminhar registros", + "body": "No modo EXEC privilegiado do seu Cisco switch, habilite o syslog e aponte-o para o host do Collector na porta {{port}}:" + } + }, + "ciscoMeraki": { + "source": "Cisco Meraki", + "step1": { + "title": "Ativar o listener Cisco Meraki no Collector", + "body": "No host onde o Collector está instalado, execute este comando para abrir o listener de registros Cisco Meraki:", + "note": "Para usar TCP em vez de UDP, substitua udp por tcp no comando acima." + }, + "step2": { + "title": "Configurar o Meraki para encaminhar registros", + "body": "No Meraki Dashboard, vá para Network-wide → Configure → General, role até a seção Reporting e adicione um servidor syslog com o IP do Collector e a porta {{port}}. Selecione todos os papéis que deseja encaminhar." + } + }, + "ciscoFirepower": { + "source": "Cisco Firepower", + "step1": { + "title": "Ativar o listener Cisco Firepower no Collector", + "body": "No host onde o Collector está instalado, execute este comando para abrir o listener de registros Cisco Firepower:", + "note": "Para usar TCP em vez de UDP, substitua udp por tcp no comando acima." + }, + "step2": { + "title": "Configurar o Firepower para encaminhar registros", + "body": "No Firepower Management Center (FMC), vá para Devices → Platform Settings, edite ou crie uma política e navegue até Syslog → Syslog Servers. Adicione o IP do Collector com a porta {{port}} (UDP), atribua a política aos seus dispositivos e implante." + } + }, + "office365": { + "intro": { + "title": "Como funciona", + "body": "O UTMStack conecta-se ao Microsoft 365 usando um app registrado no Azure AD e consulta a API de Atividade de Gerenciamento do Office 365 para obter eventos de auditoria e segurança. Nenhum agente é instalado no seu tenant.", + "diagram": { + "source": "eventos de auditoria e segurança", + "edge": "Management API", + "utmstackSub": "correlação e alertas" + }, + "note": "O UTMStack requer apenas permissões de leitura — nenhuma permissão de escrita é solicitada." + }, + "appSection": "Registro de Aplicativo no Azure", + "steps": { + "azurePortal": { + "title": "Abrir o Microsoft Entra ID", + "body": "Abra o Portal do Azure (portal.azure.com) e clique em Microsoft Entra ID." + }, + "appRegistrations": { + "title": "Ir para Registros de aplicativos", + "body": "No menu esquerdo, clique em Registros de aplicativos." + }, + "registerApp": { + "title": "Registrar um novo aplicativo", + "body": "Clique em Novo registro. Nomeie como UTMStack O365 Agent, selecione Somente contas neste diretório organizacional (Locatário único) e clique em Registrar." + }, + "clientSecret": { + "title": "Criar um segredo do cliente", + "body": "Vá para Certificados e segredos → Novo segredo do cliente. Adicione uma descrição, defina a expiração para 730 dias (24 meses) e clique em Adicionar.", + "copyNote": "Copie o Valor do segredo imediatamente — ele é exibido apenas uma vez e não pode ser recuperado depois." + }, + "apiPermissions": { + "title": "Adicionar permissões da Office 365 Management API", + "body": "Vá para Permissões de API → Adicionar uma permissão e pesquise por Office 365 Management APIs." + }, + "activityFeed": { + "title": "Conceder permissões de ActivityFeed", + "body": "Selecione Permissões de aplicativo e adicione ActivityFeed.Read e ActivityFeed.ReadDlp. Clique em Conceder consentimento de administrador e confirme." + }, + "graphPermissions": { + "title": "Adicionar permissões do Microsoft Graph", + "body": "De volta em Adicionar uma permissão, clique em Microsoft Graph." + }, + "delegatedPermissions": { + "title": "Adicionar permissões delegadas de SecurityAlert", + "body": "Selecione Permissões delegadas e adicione SecurityAlert.Read.All e SecurityAlert.ReadWrite.All. Clique em Conceder consentimento de administrador e confirme." + }, + "appPermissions": { + "title": "Adicionar permissões de aplicativo de SecurityAlert", + "body": "Selecione Permissões de aplicativo e adicione SecurityAlert.Read.All e SecurityAlert.ReadWrite.All. Clique em Conceder consentimento de administrador e confirme." + }, + "noteIds": { + "title": "Copiar os IDs do aplicativo", + "body": "Vá para a Visão geral do app e copie o ID do aplicativo (cliente) e o ID do diretório (locatário). Você também precisará do valor do segredo copiado na etapa 4." + } + }, + "credentialsSection": "Credenciais", + "credentials": { + "title": "Conectar seu tenant do Microsoft 365", + "body": "Insira os dados das etapas acima. O UTMStack verifica as credenciais antes de salvá-las. Você pode adicionar múltiplos grupos de configuração." + }, + "fields": { + "tenantId": { + "label": "Tenant ID (ID de diretório)" + }, + "clientId": { + "label": "Client ID (ID de aplicativo)" + }, + "clientSecret": { + "label": "Segredo do cliente" + }, + "cloudEnv": { + "label": "Ambiente de nuvem (opcional)", + "hint": "Commercial (padrão), GCC, GCCHigh ou DoD" + } + } + }, + "github": { + "source": "GitHub", + "step1": { + "title": "Ativar o listener de webhook do GitHub no Collector", + "body": "No host onde o Collector está instalado, execute este comando para abrir o listener HTTPS de webhook para o GitHub:", + "tokenNote": "O terminal exibirá um token secreto — copie-o imediatamente. Ele não será exibido novamente." + }, + "certWarning": { + "title": "GitHub requer um certificado TLS assinado por uma CA", + "body": "O GitHub só entrega webhooks para endpoints HTTPS com um certificado emitido por uma CA pública (certificados auto-assinados são rejeitados). Certifique-se de que o host do Collector tenha um certificado de domínio válido antes de registrar o webhook." + }, + "step2": { + "title": "Registrar o webhook no GitHub", + "body": "No seu repositório ou organização, vá para Settings → Webhooks → Add webhook e preencha o formulário:", + "payloadUrl": "Payload URL", + "contentType": "Content type", + "secret": "Secret", + "secretHint": "Cole o token impresso pelo Collector na etapa anterior.", + "events": "Which events", + "eventsHint": "Send me everything — ou selecione tipos de eventos específicos." + } + }, + "aix": { + "source": "Servidor AIX", + "step1": { + "title": "Ativar o listener AIX no Collector", + "body": "No host onde o Collector está instalado, execute este comando para abrir o listener de registros AIX:", + "note": "Para usar TCP em vez de UDP, substitua udp por tcp no comando acima." + }, + "step2": { + "title": "Configurar o AIX para encaminhar registros", + "body": "No seu sistema AIX, configure o serviço syslog para redirecionar seus registros ao host do Collector na porta {{port}}. Consulte a documentação da IBM para a sintaxe exata — ela varia entre versões do AIX." + } + }, + "as400": { + "intro": { + "title": "Como funciona", + "body": "O Coletor AS/400 é um serviço Linux que se conecta diretamente aos seus sistemas AS/400 (IBM i) e extrai entradas do diário de segurança, transmitindo-as com segurança ao UTMStack para correlação e alertas.", + "note": "Nada é instalado no AS/400 — o Coletor é executado em um host Linux que tenha acesso de rede aos seus sistemas AS/400.", + "diagram": { + "source": "seus diários", + "edge1": "diários", + "collector": "Coletor AS/400", + "collectorSub": "extrai do AS/400", + "edge2": "seguro", + "utmstackSub": "alertas e correlação" + } + }, + "install": { + "title": "Instalar o Coletor AS/400", + "body": "Execute este comando em um host Linux que possa alcançar tanto o UTMStack quanto seus sistemas AS/400 pela rede.", + "reuse": "Já tem o Coletor AS/400 instalado? Pule esta etapa — apenas adicione seus servidores ao arquivo de configuração na próxima etapa." + }, + "configure": { + "title": "Adicionar seus servidores AS/400", + "body": "Edite o as400-config.yaml no diretório de instalação do coletor e adicione cada sistema AS/400 que deseja monitorar:", + "note": "Você pode listar múltiplos servidores. O coletor monitora este arquivo e recarrega automaticamente ao salvar — sem necessidade de reinicialização." + }, + "journal": { + "title": "Ativar o diário de auditoria no AS/400", + "body": "Em cada sistema AS/400, certifique-se de que o diário de auditoria de segurança QAUDJRN esteja ativo. Consulte a documentação da IBM para as etapas exatas — o procedimento varia entre versões do IBM i." + }, + "uninstall": { + "title": "Opcional — Desinstalar o Coletor", + "body": "Execute este comando no host onde o Coletor AS/400 está instalado para parar o serviço e remover todos os arquivos." + } + }, + "bitdefender": { + "intro": { + "title": "Como funciona", + "body": "UTMStack conecta-se ao Bitdefender GravityZone usando sua chave de API para configurar o Event Push Service. O GravityZone então envia eventos de segurança diretamente ao UTMStack para correlação e alertas.", + "diagram": { + "source": "eventos de endpoints", + "edge": "Event Push Service", + "utmstackSub": "alertas e correlação" + }, + "note": "Nenhum agente é instalado no GravityZone — UTMStack registra-se como destino de push usando credenciais de API somente leitura." + }, + "whitelist": { + "title": "Adicionar IPs da Bitdefender à whitelist", + "body": "Os seguintes endereços IP do Bitdefender GravityZone devem ser permitidos no seu firewall na porta 8000 para que o Event Push Service possa alcançar o UTMStack:", + "note": "Adicione esses IPs ao seu firewall ou grupo de segurança antes de concluir a configuração." + }, + "apiSection": "Obter credenciais de API", + "api": { + "myAccount": { + "title": "Abrir Minha Conta", + "body": "No console do Bitdefender GravityZone, clique em My Account." + }, + "accessUrl": { + "title": "Anotar a Access URL", + "body": "Role até a seção Control Center API e salve a Access URL — você a inserirá no formulário de credenciais. Em seguida, abra a seção de chaves de API e clique em Add." + }, + "createKey": { + "title": "Criar uma chave de API", + "body": "Escreva uma descrição para a chave de API, selecione a opção Event Push Service API e clique em Save. Copie a chave gerada." + } + }, + "companySection": "Obter IDs de empresa", + "company": { + "myCompany": { + "title": "Abrir Minha Empresa", + "body": "No console do GravityZone, clique em My Company." + }, + "licensing": { + "title": "Anotar os IDs de empresa", + "body": "Abra a seção Licensing e salve os Company IDs que deseja monitorar — insira-os separados por vírgula no formulário de credenciais." + } + }, + "credentials": { + "title": "Inserir credenciais", + "body": "Preencha a Access URL, a chave de API, o IP público do UTMStack (onde o GravityZone enviará os eventos) e os IDs de empresa a monitorar. UTMStack verifica as credenciais antes de salvar." + }, + "fields": { + "accessUrl": { + "label": "Access URL do GravityZone" + }, + "connectionKey": { + "label": "Chave de API" + }, + "utmPublicIP": { + "label": "IP público do UTMStack" + }, + "companyIds": { + "label": "IDs de empresa (separados por vírgula)" + } + } + }, + "netflow": { + "source": "Dispositivo de rede", + "step1": { + "title": "Ativar o listener de NetFlow no Collector", + "body": "No host onde o Collector está instalado, execute este comando para abrir o coletor NetFlow na porta 2055:", + "note": "NetFlow usa apenas UDP — TCP e TLS não são suportados para este protocolo." + }, + "step2": { + "title": "Configurar o dispositivo para exportar NetFlow", + "body": "Aponte a exportação de NetFlow no seu roteador ou firewall para o host do Collector na porta {{port}} UDP. O exemplo abaixo é para Cisco IOS — consulte a documentação do seu fabricante para outras plataformas:", + "note": "Substitua pelo nome da interface onde o tráfego deve ser monitorado (ex: GigabitEthernet0/0). Aplique ingress/egress em cada interface relevante." + } + }, + "sophos": { + "intro": { + "title": "Sophos Central — Plugin de API", + "body": "O Sophos Central fornece APIs seguras para recuperar dados de eventos e alertas. O UTMStack conecta-se a essas APIs para centralizar o monitoramento e aprimorar a visibilidade de segurança — sem agente ou collector.", + "diagram": { + "source": "API do Sophos Central", + "edge": "HTTPS API", + "utmstackSub": "Ingere e correlaciona" + }, + "note": "O UTMStack consulta a API do Sophos Central periodicamente. Certifique-se de que as credenciais criadas tenham acesso de leitura a eventos e alertas." + }, + "apiSection": "Gerar credenciais de API no Sophos Central", + "steps": { + "apiCredentials": { + "title": "Abrir o gerenciamento de credenciais de API", + "body": "No Sophos Central Admin, navegue até Global Settings → API Credentials Management." + }, + "addCredential": { + "title": "Criar uma nova credencial", + "body": "Clique em Add Credential. Forneça um Nome e uma Descrição, selecione o Papel apropriado e clique em Add." + }, + "copyIds": { + "title": "Copiar Client ID e Client Secret", + "body": "Copie o Client ID e o Client Secret e armazene-os com segurança.", + "secretNote": "O Client Secret é exibido apenas uma vez. Salve-o antes de fechar esta janela." + } + }, + "credentialsSection": "Conectar ao UTMStack", + "credentials": { + "title": "Adicionar credenciais do Sophos Central", + "body": "Insira as credenciais que você acabou de criar. Você pode adicionar mais de uma conta Sophos clicando em Adicionar grupo de configuração." + }, + "fields": { + "clientId": { + "label": "Client ID" + }, + "apiKey": { + "label": "Client Secret / API Key" + } + } + }, + "mikrotik": { + "source": "Roteador MikroTik", + "step1": { + "title": "Ativar o listener do MikroTik no Collector", + "body": "No host onde o Collector está instalado, execute este comando para abrir o listener syslog do MikroTik:", + "note": "Para usar TCP em vez de UDP, substitua udp por tcp no comando acima." + }, + "step2": { + "title": "Configurar o MikroTik para encaminhar registros", + "body": "No roteador MikroTik, crie uma ação de logging remota apontando para o host do Collector na porta {{port}} e atribua-a aos tópicos relevantes. Execute o seguinte na CLI do RouterOS (Terminal no Winbox):", + "note": "Você também pode configurar pelo Winbox: System → Logging → aba Actions (adicione uma ação Remote) → depois aba Rules (adicione regras apontando para a nova ação)." + } + }, + "oracle": { + "source": "Servidor Oracle DB", + "step1": { + "title": "Ativar a integração Oracle no Collector", + "body": "No servidor onde o Collector está instalado, execute o seguinte comando para começar a receber logs do Oracle:", + "note": "O Collector começará a receber eventos syslog do Oracle na porta 7021." + }, + "step2": { + "title": "Configurar rsyslog no servidor Oracle", + "body": "Crie o arquivo de configuração do rsyslog:", + "editBody": "Abra o arquivo com seu editor preferido e adicione a seguinte configuração. Substitua BASEDIR pelo caminho de instalação do Oracle (ex.: /u01/app/oracle) e pelo endereço IP ou nome do host do Collector:", + "note": "Use @@:7021 em vez de @ se preferir entrega via TCP." + }, + "step3": { + "title": "Reiniciar o rsyslog", + "body": "Aplique a nova configuração reiniciando o serviço rsyslog:" + }, + "step4": { + "title": "Validar a configuração", + "body": "Envie mensagens de teste para verificar que o UTMStack está recebendo eventos das três fontes de logs do Oracle:", + "note": "Abra o Log Explorer e pesquise pelo texto da mensagem de teste acima para confirmar que chegaram." + } + }, + "utmstack": { + "intro": { + "title": "Como funciona", + "body": "Esta integração automonitora sua implantação do UTMStack. Um coletor leve instalado no host do UTMStack lê os logs dos próprios contêineres Docker da plataforma e os envia de volta ao UTMStack para correlação e alertas.", + "diagram": { + "source": "Logs do Docker", + "sourceSub": "Contêineres do UTMStack", + "edge1": "lê", + "collector": "Coletor", + "collectorSub": "no host", + "edge2": "ingestão", + "utmstackSub": "Correlaciona e alerta" + } + }, + "requirements": { + "title": "Executa apenas no host do UTMStack", + "body": "Esta integração só pode ser instalada em uma instância do UTMStack que execute Ubuntu ou uma distribuição da família Red Hat. Instale o coletor diretamente no servidor do UTMStack." + }, + "install": { + "title": "Instalar o coletor", + "body": "No host do UTMStack, escolha seu sistema operacional e execute o comando abaixo para baixar e instalar o coletor de automonitoramento:", + "sensitiveWarning": "Este comando contém um token de conexão sensível. Trate-o como uma senha e não o compartilhe." + }, + "after": { + "title": "O que você verá após instalar", + "item1": "O coletor se registra e aparece em Fontes de dados.", + "item2": "Os logs dos contêineres do UTMStack começam a fluir em menos de um minuto.", + "item3": "Os eventos ficam pesquisáveis no Log Explorer sob o tipo de dado utmstack." + }, + "uninstall": { + "title": "Desinstalar o coletor", + "body": "Para remover o coletor de automonitoramento do host do UTMStack, execute:" + } + }, + "endpoint": { + "title": "Detalhes de conexão", + "hint": "Configure o {{name}} para encaminhar seus logs ao Collector usando o host e a porta abaixo." + }, + "syslog": { + "sections": { + "sendLogs": { + "title": "1 · Enviar logs ao UTMStack", + "body": "Configure seu dispositivo para enviar mensagens syslog via UDP (514) ou TCP (514) ao agente UTMStack." + }, + "enableCollector": { + "title": "2 · Ativar o coletor syslog", + "body": "Ative o coletor de logs e a integração syslog no arquivo de configuração onde o agente UTMStack está instalado." + }, + "activate": { + "title": "3 · Ativar", + "body": "Ative o módulo UTMStack para que os eventos comecem a fluir para o Log Explorer." + } + } + }, + "vmware": { + "source": "VMware ESXi", + "step1": { + "title": "Ativar o listener VMware no Collector", + "body": "No host onde o Collector está instalado, execute este comando para abrir o listener syslog do VMware ESXi. O ESXi transmite via TCP:", + "note": "Para um canal criptografado, use tls em vez de tcp (carregue os certificados no Collector primeiro)." + }, + "step2": { + "title": "Apontar o syslog do ESXi para o Collector", + "body": "Abra uma sessão SSH/ESXi Shell no host (ou use o vSphere Client: Host → Configure → Advanced System Settings → Syslog.global.logHost). Defina o loghost remoto como {{host}}:{{port}} e recarregue a configuração:", + "note": "No vSphere, você pode definir Syslog.global.logHost com o mesmo valor tcp://host:port em vez de executar esxcli." + }, + "step3": { + "title": "Abrir o firewall do ESXi para syslog", + "body": "Permita o tráfego syslog de saída pelo firewall do ESXi para que o host alcance o Collector:" + } + }, + "eset": { + "source": "ESET Protect", + "step1": { + "title": "Ativar o listener ESET no Collector", + "body": "No host onde o Collector está instalado, execute este comando para abrir o listener syslog do ESET:", + "note": "Para usar TCP em vez de UDP, substitua udp por tcp no comando acima." + }, + "console": { + "moreMenu": { + "title": "Abrir o menu More", + "body": "Na barra lateral do console ESET Protect, clique no menu More." + }, + "serverConfig": { + "title": "Abrir as configurações do servidor", + "body": "Em More, abra a seção Server settings (Server configuration)." + }, + "advanced": { + "title": "Expandir as configurações avançadas", + "body": "Clique em Advanced settings para expandir a lista completa de opções de configuração." + }, + "syslog": { + "title": "Configurar o servidor Syslog", + "body": "Role até Syslog server, ative Export logs to Syslog e defina o destino como o host do Collector na porta {{port}} (UDP). O ESET envia LEEF/syslog, que o Collector ingere como o tipo de dado antivirus-esmc-eset." + } + } + }, + "kaspersky": { + "source": "Kaspersky Security", + "step1": { + "title": "Ativar o listener Kaspersky no Collector", + "body": "No host onde o Collector está instalado, execute este comando para abrir o listener syslog do Kaspersky:", + "note": "Para usar TCP em vez de UDP, substitua udp por tcp no comando acima." + }, + "console": { + "consoleSettings": { + "title": "Abrir Console settings → Integration", + "body": "Na barra lateral do Kaspersky Security Center, abra Console settings e clique no submenu Integration." + }, + "siem": { + "title": "Abrir as configurações de integração SIEM", + "body": "Em Integration, selecione SIEM e clique no link Settings para abrir a configuração de exportação." + }, + "configure": { + "title": "Configurar a exportação SIEM", + "body": "Ative a exportação e configure o Kaspersky para enviar eventos no formato Splunk (CEF) ao host do Collector na porta {{port}} (UDP). O Collector os ingere como o tipo de dado antivirus-kaspersky." + } + } + }, + "webroot": { + "sections": { + "login": { + "title": "1 · Acessar o console de gerenciamento", + "body": "Acesse o console de gerenciamento do Webroot. Ele abre na aba Sites." + }, + "openSettings": { + "title": "2 · Abrir Configurações", + "body": "Clique na aba Settings." + }, + "apiAccess": { + "title": "3 · Abrir API Access", + "body": "Na aba Subscriptions, clique na aba API Access." + }, + "createCredential": { + "title": "4 · Criar uma credencial de cliente", + "body": "Clique em New e preencha o Name e a Description. Leia o acordo SecureAnywhere Business Solution and Unity API e clique em Create." + }, + "noteClientSecret": { + "title": "5 · Copiar o ID e o segredo do cliente", + "body": "Salve o Client ID da lista e o Client Secret exibido apenas uma vez. Clique em \"I have made note of the client secret\" para confirmar." + }, + "fillForm": { + "title": "6 · Preencher o formulário", + "body": "Forneça o client ID e o client secret ao UTMStack. Você pode adicionar mais de um grupo de configuração do Webroot se necessário." + }, + "activate": { + "title": "7 · Ativar", + "body": "Ative o módulo UTMStack para que os eventos do Webroot comecem a fluir." + } + } + }, + "sentinelOne": { + "source": "SentinelOne", + "step1": { + "title": "Ativar o listener SentinelOne no Collector", + "body": "No host onde o Collector está instalado, execute este comando para abrir o listener syslog do SentinelOne. O SentinelOne transmite CEF via TCP:", + "note": "Para um canal criptografado, use tls em vez de tcp (carregue os certificados no Collector primeiro)." + }, + "console": { + "settings": { + "title": "Abrir as Configurações do SentinelOne", + "body": "Na barra lateral do console de gerenciamento do SentinelOne, clique no menu Settings." + }, + "syslog": { + "title": "Configurar a integração Syslog", + "body": "Vá para Integrations → Syslog e ative. Defina o host como {{host}} e a porta como {{port}}, mantenha o formato como CEF, clique em Test para verificar a conexão e depois em Save." + } + } + }, + "salesforce": { + "sections": { + "openSetup": { + "title": "1 · Abrir Configuração", + "body": "Vá para Setup e selecione \"Setup for the current app\" no canto superior direito da tela." + }, + "appManager": { + "title": "2 · Abrir o App Manager", + "body": "Digite \"App Manager\" na caixa de busca rápida e selecione App Manager." + }, + "newConnectedApp": { + "title": "3 · Criar um novo Connected App", + "body": "Na tela do Lightning Experience App Manager, clique em \"New Connected App\" e preencha os campos." + }, + "oauthSettings": { + "title": "4 · Ativar as Configurações OAuth", + "body": "Na seção \"API (Enable OAuth Settings)\", marque \"Enable OAuth Settings\" e use https://login.salesforce.com/services/oauth2/success como Callback URL." + }, + "oauthScopes": { + "title": "5 · Adicionar escopos OAuth", + "body": "Selecione \"Access Connect REST API resources (chatter_api)\" em Selected OAuth Scopes." + }, + "save": { + "title": "6 · Salvar", + "body": "Salve suas alterações e selecione Continue na próxima tela." + }, + "manageConsumer": { + "title": "7 · Abrir Manage Consumer Details", + "body": "Dentro do seu Connected App, vá para \"API (Enable OAuth Settings)\" e clique em \"Manage Consumer Details\" ao lado de Consumer Key and Secret." + }, + "copyCredentials": { + "title": "8 · Copiar a chave e o segredo do consumidor", + "body": "Verifique sua identidade. O Consumer Key e o Consumer Secret aparecem em \"Consumer Details\". Copie ambos com o botão Copy." + }, + "fillForm": { + "title": "9 · Preencher o formulário", + "body": "Forneça o Consumer Key, Consumer Secret, nome de usuário e senha do Salesforce ao UTMStack." + }, + "activate": { + "title": "10 · Ativar", + "body": "Ative o módulo UTMStack para que os eventos do Salesforce comecem a fluir." + } + } + }, + "iis": { + "sections": { + "enableModule": { + "title": "1 · Ativar o módulo IIS do Filebeat", + "body": "No host do agente UTMStack, execute:\ncd \"C:\\Program Files\\UTMStack\\UTMStack Agent\\beats\\filebeat\\\" && filebeat modules enable iis" + }, + "configureModule": { + "title": "2 · Configurar o módulo IIS", + "body": "Edite C:\\Program Files\\UTMStack\\UTMStack Agent\\beats\\filebeat\\modules.d\\iis.yml conforme mostrado abaixo para apontar os diretórios de logs IIS que deseja enviar." + }, + "activate": { + "title": "3 · Ativar", + "body": "Ative o módulo UTMStack para que os eventos IIS comecem a fluir." + } + } + }, + "filebeat": { + "sections": { + "installRsyslog": { + "title": "1 · Instalar rsyslog", + "body": "Certifique-se de que o rsyslog está instalado no host. Use o gerenciador de pacotes da sua distribuição (apt, dnf, yum)." + }, + "configureRsyslog": { + "title": "2 · Configurar o rsyslog para encaminhar ao UTMStack", + "body": "Edite /etc/rsyslog.conf (ou um arquivo em /etc/rsyslog.d/) e adicione uma regra de encaminhamento que direcione para o agente UTMStack via UDP ou TCP na porta 514." + }, + "restartRsyslog": { + "title": "3 · Reiniciar o rsyslog", + "body": "Reinicie o serviço rsyslog: sudo systemctl restart rsyslog" + }, + "enableCollector": { + "title": "4 · Ativar o coletor de logs do Linux", + "body": "Ative o coletor de logs e a integração de Linux Logs no arquivo de configuração onde o agente UTMStack está instalado." + } + } + }, + "json": { + "sections": { + "overview": { + "title": "1 · Usar o endpoint de ingestão HTTP/JSON", + "body": "O UTMStack aceita eventos JSON arbitrários via HTTPS. Envie uma requisição POST com uma lista de eventos; o UTMStack os processa e roteia pelo parser configurado." + }, + "auth": { + "title": "2 · Autenticar com um token de federação", + "body": "Obtenha um token de federação em Configurações → Connection Key e envie-o como Bearer token no cabeçalho Authorization." + } + }, + "endpoint": { + "title": "Endpoint de ingestão JSON", + "hint": "Use este formato de requisição na sua aplicação ou em um cron job. O token é a chave de federação em Configurações → Connection Key." + } + }, + "ldap": { + "sections": { + "openServerManager": { + "title": "1 · Abrir o Server Manager", + "body": "No controlador de domínio AD, abra o Server Manager." + }, + "addRoles": { + "title": "2 · Adicionar Funções e Recursos", + "body": "Escolha \"Adicionar funções e recursos\" no menu Gerenciar." + }, + "selectCertServices": { + "title": "3 · Selecionar Active Directory Certificate Services", + "body": "Na etapa de Funções do Servidor, selecione Active Directory Certificate Services." + }, + "installServices": { + "title": "4 · Instalar o serviço de função da Autoridade de Certificação", + "body": "Na etapa de Serviços de Função, selecione Autoridade de Certificação e conclua o assistente." + }, + "configureAdCs": { + "title": "5 · Configurar o AD CS", + "body": "Após a instalação, clique na notificação para configurar o AD CS e escolha Autoridade de Certificação como o serviço de função a configurar." + }, + "pickCaType": { + "title": "6 · Escolher o tipo de CA", + "body": "Escolha Enterprise CA → Root CA → Criar uma nova chave privada." + }, + "setValidity": { + "title": "7 · Definir o período de validade do certificado", + "body": "Defina um período de validade adequado para sua organização (5 anos é o habitual)." + }, + "confirm": { + "title": "8 · Confirmar e instalar", + "body": "Revise as configurações e clique em Configurar para concluir." + }, + "restart": { + "title": "9 · Reiniciar o controlador de domínio", + "body": "Reinicie o controlador de domínio para que LDAPS fique disponível na porta TCP 636." + }, + "activate": { + "title": "10 · Ativar", + "body": "Ative o módulo UTMStack para que os eventos de auditoria do AD comecem a fluir." + } + } + }, + "vulnerabilities": { + "sections": { + "overview": { + "title": "1 · Sobre o scanner de vulnerabilidades", + "body": "O módulo de vulnerabilidades do UTMStack escaneia os ativos descobertos pelo módulo de Gerenciamento de Ativos e compara a impressão digital deles com o banco de dados CVE." + }, + "scope": { + "title": "2 · Definir o escopo da varredura", + "body": "Use o módulo de Gerenciamento de Ativos para registrar os hosts que deseja escanear. O scanner de vulnerabilidades será executado periodicamente contra eles." + }, + "activate": { + "title": "3 · Ativar", + "body": "Ative o módulo UTMStack para iniciar a varredura." + } + } + }, + "assetScanner": { + "sections": { + "overview": { + "title": "1 · Sobre o Gerenciamento de Ativos", + "body": "O módulo de Gerenciamento de Ativos descobre e inventaria hosts, softwares e serviços em toda a sua rede." + }, + "agentRequirement": { + "title": "2 · Requisito do agente", + "body": "A descoberta de ativos usa agentes UTMStack em execução em hosts Linux, Windows ou macOS. Instale o agente nos sistemas que deseja inventariar." + }, + "activate": { + "title": "3 · Ativar", + "body": "Ative o módulo UTMStack para iniciar a descoberta de ativos." + } + } + }, + "fileIntegrity": { + "sections": { + "enableAuditPolicy": { + "title": "1 · Ativar a Auditoria de Acesso a Objetos", + "body": "No host Windows, abra Política de Grupo → Configuração do Computador → Configurações do Windows → Configurações de Segurança → Configuração de Política de Auditoria Avançada → Acesso a Objetos e ative \"Auditar Sistema de Arquivos\"." + }, + "configureFolderAuditing": { + "title": "2 · Configurar auditoria de pastas", + "body": "Em cada pasta que deseja monitorar, abra Propriedades → Segurança → Avançado → Auditoria e adicione uma entrada de auditoria para os responsáveis e tipos de acesso desejados." + }, + "verifyEvents": { + "title": "3 · Verificar se os eventos aparecem no log de Segurança", + "body": "Abra o Visualizador de Eventos e confirme que os eventos 4663/4670 estão sendo gerados quando os objetos auditados são acessados." + }, + "activate": { + "title": "4 · Ativar", + "body": "Ative o módulo UTMStack para que os eventos de integridade de arquivos comecem a fluir." + } + } + }, + "socAi": { + "sections": { + "overview": { + "title": "1 · Sobre o SOC AI", + "body": "O SOC AI aprimora o UTMStack com um analista baseado em LLM que resume alertas e sugere próximos passos. Ele opera com o provedor que você configurar." + }, + "chooseProvider": { + "title": "2 · Escolher um provedor", + "body": "Escolha um provedor — OpenAI, Anthropic, Azure OpenAI, Google Gemini, Ollama, Mistral, DeepSeek, Groq ou um endpoint personalizado compatível com OpenAI." + }, + "configureCredentials": { + "title": "3 · Configurar credenciais", + "body": "Forneça a chave de API e (quando aplicável) o nome do modelo e a URL do endpoint." + }, + "activate": { + "title": "4 · Ativar", + "body": "Ative o módulo UTMStack para que o SOC AI comece a analisar os alertas." + } + } + }, + "windowsFaa": { + "sections": { + "enableAuditPolicy": { + "title": "1 · Ativar a Auditoria de Acesso a Objetos", + "body": "No host Windows, abra Política de Grupo → Configuração do Computador → Configurações do Windows → Configurações de Segurança → Configuração de Política de Auditoria Avançada → Acesso a Objetos e ative \"Auditar Sistema de Arquivos\"." + }, + "configureFolderAuditing": { + "title": "2 · Configurar auditoria de pastas", + "body": "Em cada pasta que deseja monitorar, abra Propriedades → Segurança → Avançado → Auditoria e adicione uma entrada de auditoria para os responsáveis e tipos de acesso desejados." + }, + "activate": { + "title": "3 · Ativar", + "body": "Ative o módulo UTMStack para que os eventos de atividade de arquivos comecem a fluir." + } + } + }, + "awsBeanstalk": { + "sections": { + "openConsole": { + "title": "1 · Abrir o console do Elastic Beanstalk", + "body": "No console da AWS, abra o Elastic Beanstalk." + }, + "environment": { + "title": "2 · Abrir a página de gerenciamento do ambiente", + "body": "Navegue até a página de gerenciamento do ambiente que deseja monitorar." + }, + "configuration": { + "title": "3 · Abrir Configuração", + "body": "Escolha Configuração." + }, + "software": { + "title": "4 · Modificar a configuração de Software", + "body": "Na categoria de configuração de Software, escolha Modificar." + }, + "s3LogStorage": { + "title": "5 · Ativar armazenamento de logs no S3", + "body": "Em armazenamento de logs S3, escolha Rotacionar logs para enviar os logs rotacionados ao Amazon S3." + }, + "cloudwatchStreaming": { + "title": "6 · Ativar o streaming do CloudWatch Logs", + "body": "Em Streaming de logs de instância para CloudWatch Logs, ative o streaming, defina o período de retenção e escolha se deseja enviar os logs existentes." + }, + "activate": { + "title": "7 · Ativar", + "body": "Ative o módulo UTMStack para que os eventos do Beanstalk comecem a fluir." + } + } + }, + "awsFargate": { + "sections": { + "taskDefinition": { + "title": "1 · Atualizar a definição de tarefa", + "body": "Na definição de tarefa do Fargate, defina logDriver como \"awslogs\" e especifique o nome do grupo de logs." + }, + "cloudwatchLogs": { + "title": "2 · Confirmar que o CloudWatch Logs está recebendo logs", + "body": "Abra o console do CloudWatch Logs e confirme que o grupo de logs está sendo preenchido quando as tarefas são executadas." + }, + "iamPrerequisite": { + "title": "3 · Pré-requisito do usuário IAM", + "body": "Esta integração compartilha credenciais com o módulo AWS IAM User — certifique-se de que ele está configurado com CloudWatchLogsReadOnlyAccess." + }, + "activate": { + "title": "4 · Ativar", + "body": "Ative o módulo UTMStack para que os eventos do Fargate comecem a fluir." + } + } + }, + "awsIamUser": { + "sections": { + "iamConsole": { + "title": "1 · Abrir o console IAM", + "body": "No console da AWS, acesse IAM → Users → Add users." + }, + "createUser": { + "title": "2 · Criar o usuário", + "body": "Escolha um nome de usuário (ex.: utmstack-ingest). Selecione acesso programático." + }, + "programmaticAccess": { + "title": "3 · Definir o tipo de credencial", + "body": "Selecione \"Chave de acesso — Acesso programático\"." + }, + "attachPolicy": { + "title": "4 · Anexar a política de leitura do CloudWatch", + "body": "Anexe a política gerenciada pela AWS CloudWatchLogsReadOnlyAccess." + }, + "review": { + "title": "5 · Revisar o usuário", + "body": "Revise os detalhes do usuário e clique em Criar usuário." + }, + "copyKeys": { + "title": "6 · Copiar o ID da chave de acesso e o segredo", + "body": "Copie o ID da chave de acesso e a Chave de acesso secreta — o segredo é exibido apenas uma vez." + }, + "createLogGroup": { + "title": "7 · Criar um grupo de logs do CloudWatch", + "body": "No CloudWatch → Log groups, crie um grupo de logs com o nome \"utmstack\" — outras integrações AWS serão entregues a ele." + }, + "fillForm": { + "title": "8 · Preencher o formulário", + "body": "Forneça a chave de acesso, o segredo, a região padrão e o nome do grupo de logs (ex.: \"utmstack\") ao UTMStack." + }, + "activate": { + "title": "9 · Ativar", + "body": "Ative o módulo do UTMStack para que os eventos AWS comecem a fluir." + } + } + }, + "awsLambda": { + "sections": { + "iamPrerequisite": { + "title": "1 · Pré-requisito de usuário IAM", + "body": "O Lambda depende do módulo de usuário AWS IAM — certifique-se de que essa integração esteja configurada primeiro com CloudWatchLogsReadOnlyAccess." + }, + "cloudwatchStream": { + "title": "2 · Lambda já transmite para o CloudWatch Logs", + "body": "O AWS Lambda publica automaticamente os logs de execução no CloudWatch Logs em /aws/lambda/. O UTMStack ingere dados do grupo de logs configurado na etapa de usuário IAM." + }, + "activate": { + "title": "3 · Ativar", + "body": "Ative o módulo do UTMStack para que os eventos do Lambda comecem a fluir." + } + } + }, + "awsSqlServer": { + "sections": { + "openRds": { + "title": "1 · Abrir o console do Amazon RDS", + "body": "Abra https://console.aws.amazon.com/rds/." + }, + "pickDb": { + "title": "2 · Selecionar a instância do banco de dados", + "body": "No painel de navegação, escolha Databases e selecione a instância de banco de dados que deseja monitorar." + }, + "modify": { + "title": "3 · Modificar a instância", + "body": "Escolha Modify." + }, + "logExports": { + "title": "4 · Habilitar exportação de logs", + "body": "Na seção Log exports, escolha Error log e Agent log para publicar no CloudWatch Logs." + }, + "apply": { + "title": "5 · Aplicar alterações", + "body": "Escolha Continue e, em seguida, Modify DB Instance na página de resumo." + }, + "activate": { + "title": "6 · Ativar", + "body": "Ative o módulo do UTMStack para que os eventos do SQL Server comecem a fluir." + } + } + }, + "awsPostgresql": { + "sections": { + "openRds": { + "title": "1 · Abrir o console do Amazon RDS", + "body": "Abra https://console.aws.amazon.com/rds/." + }, + "pickDb": { + "title": "2 · Selecionar a instância do banco de dados", + "body": "No painel de navegação, escolha Databases e selecione a instância de banco de dados que deseja modificar." + }, + "logExports": { + "title": "3 · Habilitar exportação de logs", + "body": "Na seção Log exports, escolha o log PostgreSQL para publicar no CloudWatch Logs." + }, + "apply": { + "title": "4 · Aplicar alterações", + "body": "Escolha Continue e, em seguida, Modify DB Instance na página de resumo." + }, + "activate": { + "title": "5 · Ativar", + "body": "Ative o módulo do UTMStack para que os eventos do PostgreSQL comecem a fluir." + } + } + }, + "awsTrafficMirror": { + "sections": { + "createTarget": { + "title": "1 · Criar um destino de espelhamento de tráfego", + "body": "No console da VPC, crie um Traffic Mirror Target apontando para a interface de rede da VM do agente UTMStack." + }, + "createFilter": { + "title": "2 · Criar um filtro de espelhamento de tráfego", + "body": "Crie um Traffic Mirror Filter e adicione regras de entrada/saída para os protocolos que deseja espelhar (ex.: todo TCP, todo UDP)." + }, + "createSession": { + "title": "3 · Criar uma sessão de espelhamento de tráfego", + "body": "Crie uma Traffic Mirror Session que associe cada interface de rede de origem ao destino e ao filtro criados." + }, + "iamPrerequisite": { + "title": "4 · Pré-requisito de usuário IAM", + "body": "Certifique-se de que o módulo de usuário AWS IAM também esteja configurado para que o UTMStack possa ler os VPC flow logs quando necessário." + }, + "activate": { + "title": "5 · Ativar", + "body": "Ative o módulo do UTMStack para que o tráfego espelhado comece a ser analisado." + } + } + }, + "deceptivebytes": { + "source": "Deceptive Bytes", + "step1": { + "title": "Habilitar o listener do Deceptive Bytes no Collector", + "body": "No host onde o Collector está instalado, execute este comando para abrir o listener syslog do Deceptive Bytes:", + "note": "Para usar TCP em vez de UDP, substitua udp por tcp no comando acima." + }, + "step2": { + "title": "Configurar o Deceptive Bytes para encaminhar logs", + "body": "No console de gerenciamento do Deceptive Bytes, configure o encaminhamento syslog para enviar eventos ao host do Collector na porta {{port}} (UDP). O Deceptive Bytes emite syslog no formato CEF, que o Collector ingere como o tipo de dados deceptive-bytes." + } + }, + "fortigate": { + "source": "FortiGate firewall", + "step1": { + "title": "Habilitar o listener do FortiGate no Collector", + "body": "No host onde o Collector está instalado, execute este comando para abrir o listener syslog do FortiGate:", + "note": "Para usar TCP em vez de UDP, substitua udp por tcp no comando acima." + }, + "step2": { + "title": "Configurar o FortiGate para encaminhar logs", + "body": "No FortiGate, aponte o syslog para o host do Collector na porta {{port}}. Execute o seguinte na CLI do FortiOS (ou use Log & Report → Log Settings → Syslog na interface gráfica):", + "note": "Substitua o endereço do servidor se o Collector estiver em outro host. Para múltiplos coletores syslog, use syslogd2/syslogd3/syslogd4." + } + }, + "fortiweb": { + "source": "FortiWeb WAF", + "step1": { + "title": "Habilitar o listener do FortiWeb no Collector", + "body": "No host onde o Collector está instalado, execute este comando para abrir o listener syslog do FortiWeb:", + "note": "Para usar TCP em vez de UDP, substitua udp por tcp no comando acima." + }, + "step2": { + "title": "Configurar o FortiWeb para encaminhar logs", + "body": "No FortiWeb, crie uma política de syslog apontando para o host do Collector na porta {{port}} e habilite o registro via syslog. Execute o seguinte na CLI do FortiWeb (ou use Log & Report → Log Policy → Syslog Policy na interface gráfica):", + "note": "Certifique-se de que os tipos de log relevantes (Attack, Event, Traffic) estejam habilitados para envio via syslog nas configurações de Log & Report." + } + }, + "paloalto": { + "source": "Palo Alto firewall", + "step1": { + "title": "Habilitar o listener do Palo Alto no Collector", + "body": "No host onde o Collector está instalado, execute este comando para abrir o listener syslog do Palo Alto:", + "note": "Para usar TCP em vez de UDP, substitua udp por tcp no comando acima." + }, + "step2": { + "title": "Criar um perfil de servidor Syslog", + "body": "No PAN-OS, vá para Device → Server Profiles → Syslog e adicione um perfil. Defina o endereço do servidor como {{host}}, transporte UDP, porta {{port}} e formato BSD." + }, + "step3": { + "title": "Encaminhar logs e confirmar", + "body": "Crie um perfil de Log Forwarding (Objects → Log Forwarding) que envie os tipos de log Traffic, Threat e outros para o perfil syslog acima, vincule-o às regras de Security policy (Policies → Security → rule → Actions → Log Forwarding) e, em seguida, Commit." + } + }, + "pfsense": { + "source": "pfSense firewall", + "step1": { + "title": "Habilitar o listener do pfSense no Collector", + "body": "No host onde o Collector está instalado, execute este comando para abrir o listener syslog do pfSense:", + "note": "Para usar TCP em vez de UDP, substitua udp por tcp no comando acima." + }, + "step2": { + "title": "Habilitar registro remoto no pfSense", + "body": "Na interface web do pfSense, vá para Status → System Logs → Settings. Em Remote Logging Options, marque Enable Remote Logging, defina um servidor de log remoto como {{host}}:{{port}}, escolha quais logs enviar (ou Everything) e clique em Save." + } + }, + "sonicwall": { + "source": "SonicWall firewall", + "step1": { + "title": "Habilitar o listener do SonicWall no Collector", + "body": "No host onde o Collector está instalado, execute este comando para abrir o listener syslog do SonicWall:", + "note": "Para usar TCP em vez de UDP, substitua udp por tcp no comando acima." + }, + "step2": { + "title": "Adicionar um servidor Syslog no SonicOS", + "body": "No SonicOS, vá para Device → Log → Syslog (Manage → Log → Syslog em firmwares mais antigos) e adicione um Syslog Server com endereço {{host}} e porta {{port}}. Defina o Syslog Format como ArcSight (CEF) — o UTMStack analisa o SonicWall em CEF — e clique em Apply." + } + }, + "sophosxg": { + "source": "Sophos Firewall", + "step1": { + "title": "Habilitar o listener do Sophos Firewall no Collector", + "body": "No host onde o Collector está instalado, execute este comando para abrir o listener syslog do Sophos Firewall:", + "note": "Para usar TCP em vez de UDP, substitua udp por tcp no comando acima." + }, + "step2": { + "title": "Adicionar um servidor Syslog no Sophos Firewall", + "body": "No console do Sophos Firewall (SFOS), vá para System → System services → Log settings e adicione um Syslog Server com endereço {{host}} e porta {{port}}. Escolha os tipos de log que deseja encaminhar (firewall, IPS, ATP, web, etc.) e clique em Apply." + } + }, + "suricata": { + "source": "Suricata IDS", + "step1": { + "title": "Habilitar o listener do Suricata no Collector", + "body": "No host onde o Collector está instalado, execute este comando para abrir o listener do Suricata:", + "note": "Para usar TCP em vez de UDP, substitua udp por tcp no comando acima." + }, + "step2": { + "title": "Enviar logs EVE do Suricata para syslog", + "body": "O Suricata é ingerido como JSON (EVE). No host do Suricata, edite suricata.yaml e configure a saída eve-log para gravar no syslog:", + "note": "Em seguida, reinicie o Suricata: sudo systemctl restart suricata" + }, + "step3": { + "title": "Encaminhar syslog para o Collector", + "body": "Aponte a facilidade local5 (para onde o Suricata agora grava) para o Collector. Adicione esta regra em /etc/rsyslog.d/60-utmstack-suricata.conf no host do Suricata:", + "note": "Use @@ em vez de @ para TCP. Em seguida, reinicie o rsyslog: sudo systemctl restart rsyslog" + } + }, + "o365_graph": { + "intro": { + "title": "Como funciona", + "body": "O UTMStack se conecta ao Microsoft 365 com um app do Azure AD registrado e consulta o Microsoft Graph por eventos de segurança: alertas, incidentes, auditoria do diretório, sign-ins, detecções de risco, consultas de hunting e logs de auditoria do Purview. Nenhum agente é instalado no seu tenant.", + "diagram": { + "source": "eventos de segurança", + "edge": "Microsoft Graph", + "utmstackSub": "correlação & alertas" + }, + "note": "O UTMStack requer apenas acesso somente leitura à API do Graph — nenhuma permissão de gravação é solicitada." + }, + "appSection": "Registro de aplicativo Azure", + "steps": { + "azurePortal": { + "title": "Abrir o Microsoft Entra ID", + "body": "Abra o Portal do Azure (portal.azure.com) e clique em Microsoft Entra ID." + }, + "appRegistrations": { + "title": "Ir para Registros de aplicativo", + "body": "No menu à esquerda, clique em Registros de aplicativo." + }, + "registerApp": { + "title": "Registrar um novo aplicativo", + "body": "Clique em Novo registro. Nomeie-o UTMStack Graph Dev, selecione Somente contas neste diretório organizacional (Single-tenant) e clique em Registrar." + }, + "clientSecret": { + "title": "Criar um segredo de cliente", + "body": "Vá em Certificados e segredos → Novo segredo de cliente. Adicione uma descrição, defina a expiração como 730 dias (24 meses) e clique em Adicionar.", + "copyNote": "Copie o valor do segredo imediatamente — ele só é exibido uma vez e não poderá ser recuperado depois." + }, + "apiPermissions": { + "title": "Adicionar permissões do Microsoft Graph", + "body": "Vá em Permissões de API → Adicionar uma permissão e selecione Microsoft Graph, depois escolha Permissões de aplicativo." + }, + "graphPermissions": { + "title": "Adicionar as quatro permissões do Graph", + "body": "Adicione SecurityEvents.Read.All, Directory.Read.All, AuditLog.Read.All e IdentityRiskEvent.Read.All." + }, + "adminConsent": { + "title": "Conceder consentimento de administrador", + "body": "De volta em Permissões de API, clique em Conceder consentimento de administrador para {tenant} e confirme." + }, + "noteIds": { + "title": "Copiar os IDs do aplicativo", + "body": "Vá para a Visão geral do aplicativo e copie o ID do aplicativo (cliente) e o ID do diretório (tenant). Você também precisa do valor do segredo copiado na etapa 4." + } + }, + "credentialsSection": "Credenciais", + "credentials": { + "title": "Conectar seu tenant do Microsoft 365", + "body": "Insira os detalhes das etapas acima. O UTMStack verifica as credenciais antes de salvar. Você pode adicionar vários grupos de configuração." + }, + "fields": { + "tenantId": { + "label": "ID do Tenant (ID do Diretório)" + }, + "clientId": { + "label": "ID do Cliente (ID do Aplicativo)" + }, + "clientSecret": { + "label": "Segredo do Cliente" + }, + "cloudEnv": { + "label": "Ambiente de nuvem (opcional)", + "hint": "Commercial (padrão), GCC, GCCHigh ou DoD" + } + } + } + }, + "cloud": { + "howItWorksTitle": "Como funciona", + "howItWorksBody": "{{name}} executa completamente dentro do UTMStack — sem agente ou coletor para implantar. Fornece credenciais de API somente leitura e o UTMStack buscará eventos em um cronograma, analisará-os e os ingerirá no Log Explorer.", + "connectionTitle": "Conexão", + "noFields": "Nenhum campo de conexão configurado.", + "testConnection": "Testar conexão", + "save": "Salvar", + "afterTitle": "O que você verá após conectar", + "after1": "O UTMStack realiza um preenchimento inicial de eventos recentes.", + "after2": "A partir de então, os eventos são buscados a cada 1–5 minutos (depende da API).", + "after3": "A integração aparece em Fontes de dados com status atual de busca e atraso.", + "tenants": { + "title": "Grupos de configuração configurados", + "empty": "Ainda não há grupos de configuração. Adicione o primeiro abaixo.", + "loading": "Carregando grupos de configuração…", + "nameLabel": "Nome do grupo de configuração", + "namePlaceholder": "p. ex. acme-prod", + "add": "Adicionar grupo de configuração", + "update": "Atualizar grupo de configuração", + "delete": "Excluir", + "edit": "Editar", + "cancel": "Cancelar", + "editing": "Editando: {{name}}", + "selectFile": "Selecionar arquivo", + "replaceFile": "Substituir arquivo", + "fileLoaded": "Arquivo carregado", + "invalidJson": "Não foi possível ler o arquivo como JSON.", + "createError": "Não foi possível criar o grupo de configuração. Tente novamente.", + "updateError": "Não foi possível atualizar o grupo de configuração. Tente novamente.", + "createSuccess": "Grupo de configuração criado com sucesso.", + "updateSuccess": "Grupo de configuração atualizado com sucesso." + }, + "google": { + "sections": { + "createTopic": { + "title": "1 · Crie um tópico Pub/Sub", + "body": "No console do Google Cloud, abra Pub/Sub → Tópicos e crie um novo tópico. UTMStack receberá eventos por este tópico.", + "docLabel": "Abrir a página de tópicos Pub/Sub" + }, + "createSubscription": { + "title": "2 · Crie uma assinatura", + "body": "Dentro do tópico, crie uma assinatura do tipo Pull. UTMStack obtém mensagens desta assinatura." + }, + "configureSubscription": { + "title": "3 · Configure a assinatura", + "body": "Defina a duração de retenção de mensagens conforme sua tolerância a indisponibilidades (7 dias padrão é suficiente). Mantenha o prazo de confirmação em 10 segundos e expiração em «Nunca expirar»." + }, + "logsRouter": { + "title": "4 · Abra o Logs Router", + "body": "Navegue até Logging → Logs Router e crie um novo sink. Ele encaminha os logs do projeto para o tópico Pub/Sub criado acima." + }, + "sinkDestination": { + "title": "5 · Aponte o sink para o tópico", + "body": "Escolha Tópico Cloud Pub/Sub como destino do sink e selecione o tópico criado. Use filtros de inclusão/exclusão para delimitar o que é encaminhado." + }, + "serviceAccount": { + "title": "6 · Crie uma conta de serviço", + "body": "Abra IAM e administração → Contas de serviço e crie uma nova conta de serviço. Atribua a ela o papel Editor do Pub/Sub para que UTMStack possa ler da assinatura.", + "docLabel": "Abrir a página de contas de serviço" + }, + "serviceAccountKey": { + "title": "7 · Gere uma chave para a conta de serviço", + "body": "Abra a conta de serviço, vá na aba Chaves e adicione uma nova chave. Escolha JSON como tipo de chave." + }, + "downloadKey": { + "title": "8 · Baixe e carregue a chave JSON", + "body": "Salve o arquivo JSON que o Google baixa: seu conteúdo vai no campo «Chave JSON da conta de serviço» abaixo." + } + }, + "fields": { + "projectId": { + "label": "ID do projeto" + }, + "subscription": { + "label": "Nome da assinatura" + }, + "jsonKey": { + "label": "Chave JSON da conta de serviço" + } + }, + "intro": { + "title": "Como funciona", + "body": "O UTMStack lê a atividade de auditoria diretamente do Google Cloud via Pub/Sub. Um sink do Logs Router transmite os logs do seu projeto para um tópico Pub/Sub; o UTMStack executa um puller interno que lê uma assinatura Pull nesse tópico usando uma chave de conta de serviço. Nada é instalado no seu projeto GCP.", + "diagram": { + "source": "Cloud Logging", + "edge1": "Logs Router", + "pubsub": "Pub/Sub", + "pubsubSub": "tópico + assinatura", + "edge2": "coleta", + "utmstackSub": "alertas e correlação" + }, + "note": "Nenhum agente é executado no GCP — o UTMStack coleta mensagens da assinatura Pub/Sub usando a chave JSON da conta de serviço que você fornece abaixo." + }, + "credentials": { + "title": "Configuração Pub/Sub", + "body": "Use os valores coletados acima para configurar o UTMStack. Você pode monitorar mais de um projeto salvando configurações adicionais.", + "mapping": { + "intro": "Referência dos campos", + "projectId": "Project ID — o projeto GCP que contém seu tópico, assinatura e sink", + "subscription": "Nome da assinatura — a assinatura Pull criada na etapa 2", + "jsonKey": "Chave JSON da conta de serviço — o arquivo baixado na etapa 8" + } + } + }, + "azure": { + "sections": { + "sharedAccessPolicy": { + "title": "2 · Adicione uma política de acesso compartilhado", + "body": "Abra o Event Hub → Políticas de acesso compartilhado e crie uma nova política apenas com a permissão Listen." + }, + "connectionString": { + "title": "3 · Copie a string de conexão primária", + "body": "Abra a política e copie a string de conexão primária. Tem o formato: Endpoint=sb://...;SharedAccessKeyName=...;SharedAccessKey=..." + }, + "consumerGroup": { + "title": "4 · Crie um consumer group dedicado", + "body": "Abra o Event Hub → Consumer groups e crie um novo para UTMStack. Não reutilize $Default — dê ao UTMStack seu próprio grupo para que os checkpoints não colidam com outros consumers.", + "warn": "Crie um grupo de consumidores especificamente para o UTMStack. Não use $Default nem qualquer outro grupo já em uso — reutilizar um grupo de consumidores entre consumidores não relacionados pode causar comportamento inesperado e perda de eventos. Todas as instâncias UTMStack devem compartilhar o mesmo grupo de consumidores para processar eventos em conjunto." + }, + "storageContainer": { + "title": "6 · Crie um container na conta de armazenamento", + "body": "Dentro da conta de armazenamento → Containers, crie um novo container. Anote o nome do container e a string de conexão da conta (Chaves de acesso → String de conexão)." + }, + "eventGrid": { + "title": "7 · Registre o provedor de recursos Event Grid", + "body": "Em Assinaturas → Provedores de recursos, registre Microsoft.EventGrid se ainda não estiver. Isso permite que o Azure encaminhe eventos de nível de assinatura para o seu Event Hub." + }, + "createEventHub": { + "title": "Criar um Event Hub", + "body": "No Azure Portal, crie um namespace de Event Hubs e um Event Hub dentro dele. O UTMStack lerá os eventos desse hub.", + "docLabel": "Início rápido: criar um event hub usando o Azure portal" + }, + "createStorageAccount": { + "title": "Criar uma Storage Account", + "body": "O UTMStack precisa de uma Storage Account para registrar sua posição de leitura. Crie uma na mesma região que o Event Hub.", + "docLabel": "Início rápido: criar uma storage account" + }, + "storageConnection": { + "title": "Copiar a string de conexão da Storage Account", + "body": "Obtenha a string de conexão da Storage Account em: All services → Storage accounts → sua conta → Access keys. O UTMStack a utiliza para armazenar os checkpoints do Event Hub." + }, + "createEventSubscription": { + "title": "Criar uma Event Subscription", + "body": "No painel Events da assinatura, crie um novo evento clicando em Events → Event Subscription." + }, + "configureEventSubscription": { + "title": "Apontar a Event Subscription para o seu Event Hub", + "body": "Configure a Event Subscription para enviar logs ao Event Hub criado na etapa 1." + } + }, + "fields": { + "eventHubConnection": { + "label": "String de conexão do Event Hub" + }, + "consumerGroup": { + "label": "Consumer group" + }, + "storageContainer": { + "label": "Nome do container de armazenamento" + }, + "storageConnection": { + "label": "String de conexão da conta de armazenamento" + } + }, + "intro": { + "title": "Como funciona", + "body": "O UTMStack lê a atividade de auditoria diretamente de um Azure Event Hub. Você configura sua assinatura Azure para transmitir eventos para um Event Hub; o UTMStack executa um puller interno que lê esse hub e registra seu progresso em uma Storage Account. Nada é instalado no seu tenant Azure.", + "diagram": { + "source": "eventos da assinatura", + "edge1": "transmite para", + "eventHub": "Event Hub", + "eventHubSub": "fluxo de eventos", + "edge2": "coleta", + "utmstackSub": "alertas e correlação" + }, + "note": "Nenhum agente é executado no Azure — o UTMStack coleta eventos do Event Hub usando as strings de conexão que você fornece abaixo." + }, + "sampleLabel": "Exemplo de string de conexão:", + "credentials": { + "title": "Configuração do Event Hub", + "body": "Use os dados coletados nas etapas acima para configurar o UTMStack. Você pode adicionar mais de um Event Hub salvando configurações adicionais.", + "mapping": { + "intro": "Referência dos campos", + "eventHubConnection": "String de conexão do Event Hub — valor obtido na etapa 3", + "consumerGroup": "Grupo de consumidores — valor obtido na etapa 4", + "storageContainer": "Nome do container de armazenamento — valor obtido na etapa 6", + "storageConnection": "String de conexão da storage account — valor obtido na etapa 7" + } + } + }, + "aws": { + "intro": { + "title": "Como funciona", + "body": "UTMStack lê a atividade de auditoria diretamente do AWS CloudWatch Logs. O CloudTrail captura chamadas de API e eventos de gerenciamento na sua conta AWS, encaminha-os a um log group do CloudWatch, e UTMStack consulta esse grupo para ingestar e correlacionar eventos.", + "diagram": { + "source": "eventos de API", + "edge1": "CloudTrail", + "cloudwatchSub": "log groups", + "edge2": "consulta", + "utmstackSub": "alertas e correlação" + }, + "note": "Nenhum agente é instalado na AWS — UTMStack extrai os eventos de log usando credenciais IAM somente leitura que você fornece abaixo." + }, + "iamSection": "Configurar Usuário IAM", + "iam": { + "dashboard": { + "title": "Abrir o painel IAM", + "body": "Abra o console da AWS, navegue até o painel IAM e selecione Users." + }, + "addUser": { + "title": "Adicionar um usuário", + "body": "Clique em Add user, insira um nome descritivo e avance para o próximo passo." + }, + "attachPolicy": { + "title": "Vincular a política somente leitura", + "body": "Em Permissions, vincule a política necessária. Selecione CloudWatchLogsReadOnlyAccess para acesso somente leitura ao CloudWatch." + }, + "createUser": { + "title": "Criar o usuário", + "body": "Revise a configuração e clique em Create user para provisionar a conta." + }, + "openUser": { + "title": "Abrir o novo usuário", + "body": "Abra o usuário recém-criado clicando no seu nome para ver detalhes e gerenciar credenciais." + }, + "securityTab": { + "title": "Ir para Security credentials", + "body": "Selecione a aba Security credentials para criar chaves de acesso programático." + }, + "createKey": { + "title": "Criar uma chave de acesso", + "body": "Clique em Create access key e escolha a opção para um aplicativo rodando fora da AWS (acesso programático)." + }, + "confirmKey": { + "title": "Confirmar a criação", + "body": "Confirme a criação da chave de acesso. A AWS irá gerar um Access Key ID e um Secret Access Key." + }, + "downloadKey": { + "title": "Salvar as credenciais", + "body": "Baixe o arquivo de credenciais ou copie o Access Key ID e o Secret Access Key para um local seguro — o Secret Access Key é exibido apenas uma vez." + } + }, + "credentials": { + "title": "Inserir credenciais", + "body": "Cole o Access Key ID e o Secret Access Key obtidos nas etapas anteriores. UTMStack verifica as credenciais na AWS antes de salvar." + }, + "cloudwatchSection": "Configurar AWS CloudWatch", + "cloudwatch": { + "createGroup": { + "title": "Criar um CloudWatch Log Group", + "body": "Abra o console do CloudWatch, escolha Log management e clique em Create log group." + }, + "nameGroup": { + "title": "Nomear o log group e configurar retenção", + "body": "Insira o nome utmstack para o log group e defina a retenção para 1 dia. Clique em Create log group." + }, + "openTrail": { + "title": "Abrir o CloudTrail e criar um trail", + "body": "No console do CloudTrail, clique em Create trail para iniciar a configuração de um novo trail." + }, + "configureTrail": { + "title": "Configurar entrega, validação e integração com CloudWatch", + "body": "No formulário de criação do trail, defina as seguintes opções:", + "items": [ + "Nome e escopo do trail: insira um nome descritivo; ative Apply trail to all accounts in my organization se precisar de coleta em nível de organização.", + "Destino S3: escolha Create new S3 bucket (ou selecione um existente) para entrega de logs brutos.", + "Criptografia: ative Log file SSE-KMS e selecione a chave KMS apropriada.", + "Validação de arquivo de log: ative para garantir a integridade dos logs entregues (recomendado).", + "CloudWatch Logs: ative a entrega ao CloudWatch, selecione Use existing log group e insira o nome exato utmstack.", + "Função IAM: forneça ou crie a função que o CloudTrail usará para escrever no S3 e publicar no CloudWatch." + ] + }, + "eventTypes": { + "title": "Selecionar tipos de eventos", + "body": "Ative as categorias de eventos necessárias para monitoramento e auditoria.", + "management": { + "label": "1 · Eventos de gerenciamento", + "body": "Ative Management events e selecione All para registrar toda atividade de API que gerencia recursos da AWS (criar, atualizar, excluir)." + }, + "data": { + "label": "2 · Eventos de dados", + "body": "Adicione um Data event. Escolha S3 e selecione Log all events para capturar operações em nível de objeto como GetObject e PutObject." + }, + "network": { + "label": "3 · Eventos de atividade de rede", + "body": "Na seção Network Activities adicione pelo menos um serviço (ex. ec2.amazonaws.com) e ative Log all events." + } + }, + "review": { + "title": "Revisar e criar o trail", + "body": "Na tela Configure event aggregation aceite os padrões (ou ajuste se necessário). Revise todas as configurações e clique em Create trail." + } + }, + "fields": { + "accessKeyId": { + "label": "ID da chave de acesso da AWS" + }, + "secretAccessKey": { + "label": "Chave de acesso secreta da AWS" + }, + "region": { + "label": "Região padrão da AWS" + }, + "logGroupName": { + "label": "Nome do log group" + } + } + }, + "crowdstrike": { + "intro": { + "title": "Como funciona", + "body": "O UTMStack lê detecções e atividade de auditoria diretamente da API de Event Streams do CrowdStrike Falcon. Você cria um cliente de API no Falcon com escopo de Event Streams; o UTMStack executa um puller interno que transmite eventos usando essas credenciais. Nada é instalado nos seus endpoints ou no Falcon.", + "diagram": { + "source": "detecções e eventos", + "edge1": "Event Streams API", + "api": "Falcon API", + "apiSub": "fluxo de eventos", + "edge2": "coleta", + "utmstackSub": "alertas e correlação" + }, + "note": "Nenhum agente é implantado pelo UTMStack — ele coleta eventos do Falcon usando as credenciais de cliente de API somente leitura que você fornece abaixo." + }, + "sections": { + "apiClients": { + "title": "Abrir API Clients and Keys", + "body": "No console Falcon, abra o menu (ícone de hambúrguer, canto superior esquerdo) e vá para Support and resources → API Clients and Keys." + }, + "createClient": { + "title": "Criar um novo cliente de API", + "body": "Clique em Create API Client para iniciar uma nova definição de cliente." + }, + "scopes": { + "title": "Nomear o cliente e conceder escopo de Event Streams", + "body": "Dê ao cliente um nome descritivo (o UTMStack o usa para identificar a fonte de eventos) e selecione os escopos de API necessários para Event Streams. Clique em Create para gerar as credenciais." + }, + "recordCredentials": { + "title": "Registrar as credenciais", + "body": "Copie o Client ID, o Client Secret e a Base URL para a sua região CrowdStrike. O segredo é exibido apenas uma vez — armazene-o com segurança. Você colará os três no formulário abaixo." + } + }, + "credentials": { + "title": "Configuração do cliente de API", + "body": "Use as credenciais das etapas acima para configurar o UTMStack. Você pode adicionar mais de um cliente CrowdStrike salvando configurações adicionais.", + "mapping": { + "intro": "Referência dos campos", + "appName": "Nome do app — o nome descritivo do cliente da etapa 3 (identifica a fonte de eventos)", + "clientId": "Client ID — valor registrado na etapa 4", + "clientSecret": "Client Secret — valor registrado na etapa 4 (exibido apenas uma vez)", + "cloudRegionUrl": "Base URL — o endpoint da sua região, ex.: https://api.crowdstrike.com (us-1), https://api.us-2.crowdstrike.com (us-2), https://api.eu-1.crowdstrike.com (eu-1)" + } + }, + "fields": { + "appName": { + "label": "Nome do app" + }, + "clientId": { + "label": "Client ID" + }, + "clientSecret": { + "label": "Client Secret" + }, + "cloudRegionUrl": { + "label": "Base URL (região da nuvem)" + } + } + } + }, + "custom": { + "whenTitle": "Quando usar isso", + "whenBody": "Quando sua fonte não está no catálogo. Encaminhe syslog ou JSON arbitrário para o UTMStack e defina um analisador para normalizar campos.", + "endpointsTitle": "Endpoints", + "syslogUdp": "Syslog (UDP)", + "syslogTls": "Syslog (TLS)", + "httpJson": "HTTP / JSON", + "payloadTitle": "Exemplo de payload JSON", + "parserTitle": "Defina o analisador", + "parserBody": "Os eventos recebidos são armazenados sob o tipo de dado {{dataType}}. Adicione um filtro de parsing para ele de modo que o payload bruto seja mapeado em campos estruturados e, em seguida, crie regras de alerta.", + "openEditor": "Abrir editor do analisador", + "powershellLabel": "PowerShell (Executar como administrador)", + "linuxLabel": "Linux — bash", + "macosLabel": "macOS — bash", + "exampleLabel": "Exemplo de destino syslog em {{name}}:", + "intro": { + "title": "Como funciona", + "body": "Uma integração personalizada ingere logs de qualquer fonte não coberta pelos módulos integrados. Você instala o UTMStack Collector, registra um listener para seus dados com o protocolo de sua escolha e aponta sua fonte para ele.", + "note": "Escolha abaixo o protocolo que sua fonte pode enviar (syslog UDP/TCP/TLS, ou HTTP/HTTPS para JSON) — o Collector cria o tipo de dado automaticamente." + }, + "diagram": { + "source": "Sua fonte", + "sourceSub": "qualquer app ou dispositivo", + "forwarder": "Collector", + "ingests": "ingere", + "utmstackSub": "alertas e correlação" + }, + "choose": { + "title": "Escolher protocolo e porta", + "body": "Selecione como sua fonte envia dados e a porta que o Collector deve escutar, depois execute o comando de ativação no host do Collector.", + "portLabel": "Porta de escuta", + "tlsFirst": "Primeiro, carregue seu certificado e chave TLS no Collector:", + "enableLabel": "Em seguida, ative a integração:", + "authNote": "Para exigir autenticação, adicione --auth bearer (token) ou --auth hmac — o Collector imprime um token para usar no cabeçalho Authorization." + }, + "send": { + "title": "Apontar sua fonte para o Collector", + "bodyNetwork": "Configure sua fonte para enviar syslog {{proto}} para {{host}}:{{port}}. A maioria dos dispositivos possui uma configuração de syslog remoto ou encaminhamento de logs para isso.", + "bodyHttp": "Envie seus eventos como JSON via HTTP POST para {{endpoint}}. O corpo de cada requisição é um evento JSON:", + "httpBindNote": "O listener HTTP/HTTPS vincula-se a 127.0.0.1 (o host do Collector) por padrão, portanto envie requisições de um app em execução nesse host — ou coloque um proxy reverso à frente. Para fontes remotas, use syslog (UDP/TCP/TLS)." + }, + "manualCommand": { + "title": "Optional — Enable via the command line instead", + "intro": "Prefer the terminal? SSH into the Collector host and run the command below — it matches whatever protocol and port you have selected above." + } + }, + "remoteEnable": { + "title": "Ativar esta integração remotamente", + "body": "Escolha um Collector, selecione o protocolo e a porta, depois ative a integração — sem necessidade de SSH.", + "noPermission": "Você não tem permissão para gerenciar integrações remotas. Peça a um administrador para conceder a permissão integrations.write.", + "loadingCollectors": "Carregando Collectors…", + "noCollectors": "Nenhum Collector foi registrado ainda. Instale um acima para ativar integrações remotamente.", + "forwarderOffline": "Este Collector está offline e não pode receber alterações de configuração agora.", + "legendOnline": "{{count}} online", + "legendOffline": "{{count}} offline", + "legendTotal": "{{count}} total", + "forwarderLabel": "Collector", + "protoLabel": "Protocolo", + "portLabel": "Porta", + "currentStateLoading": "Verificando configuração atual…", + "currentlyEnabled": "Atualmente: ativada · {{proto}} · porta {{port}}", + "currentlyDisabled": "Atualmente: desativada · {{proto}} · porta {{port}}", + "authLabel": "Autenticação", + "authNone": "Nenhuma", + "authBearer": "Token Bearer", + "authHmac": "Assinatura HMAC", + "pathLabel": "Caminho", + "signatureHeaderLabel": "Cabeçalho de assinatura", + "certTitle": "Certificado TLS", + "certLoading": "Verificando status do certificado…", + "certLoaded": "Um certificado válido já está carregado neste Collector.", + "certMissing": "Nenhum certificado carregado ainda — envie um para ativar este protocolo.", + "certInvalid": "O certificado carregado é inválido: {{error}}", + "certPemLabel": "Certificado", + "keyPemLabel": "Chave privada", + "caPemLabel": "Certificado CA", + "uploadCertsButton": "Enviar certificado", + "certUploadSuccess": "Certificado enviado.", + "certUploadError": "Falha ao enviar o certificado.", + "certReadError": "Não foi possível ler o(s) arquivo(s) selecionado(s).", + "enableButton": "Ativar integração", + "disableButton": "Desativar integração", + "enableSuccess": "Integração ativada.", + "disableSuccess": "Integração desativada.", + "enableError": "Falha ao atualizar a integração.", + "secretWarning": "Armazene este token com segurança — não será exibido novamente.", + "sendToInstance": "Enviar para a instância", + "enterpriseFeature": "Este é um recurso Enterprise.", + "addCollector": "Adicionar Collector", + "addApiKey": "Adicionar chave de API", + "apiKeyLabel": "Chave de API", + "apiKeyHint": "Primeiro você precisará de uma chave de API.", + "apiKeyPlaceholder": "Selecionar uma chave de API", + "apiKeyAddNew": "Adicionar chave de API…", + "apiKeyNone": "Nenhuma chave de API ainda", + "forwarderNoRemoteControl": "Este forwarder foi instalado com o controlo remoto desativado. Ignora a configuração enviada daqui, e isso só pode ser alterado na própria máquina." + } + }, + "codeBlock": { + "copy": "Copiar", + "copied": "Copiado" + }, + "createDrawer": { + "title": "Nova integração personalizada", + "moduleName": "Nome do módulo", + "moduleNameHint": "Identificador único. Sem espaços.", + "moduleNamePlaceholder": "minha-app-personalizada", + "prettyName": "Nome para exibição", + "prettyNamePlaceholder": "Minha App Personalizada", + "dataType": "Tipo de dados", + "dataTypePlaceholder": "Identificador único para este tipo de dados", + "icon": "Ícone", + "iconHint": "PNG, SVG, JPEG, GIF ou WEBP. Máximo 3MB. Usado como logo da integração.", + "iconPreview": "Visualização do ícone", + "dataTypeExists": "Este tipo de dados já existe", + "invalidFileType": "O ícone deve ser um arquivo de imagem válido (PNG, JPEG, SVG, GIF, WEBP)", + "fileTooLarge": "O ícone não deve exceder 3MB", + "fileReadError": "Falha ao ler o arquivo", + "cancel": "Cancelar", + "create": "Criar integração", + "creating": "Criando…", + "editTitle": "Editar integração", + "save": "Salvar", + "saving": "Salvando…", + "currentIcon": "Ícone atual — faça upload de um arquivo para substituí-lo", + "name": "Nome da integração", + "namePlaceholder": "ex.: Acme Firewall", + "description": "Descrição", + "descriptionPlaceholder": "O que esta integração ingere e por quê (opcional)", + "identifierHint": "Armazenado como \"{{id}}\" (derivado do nome)", + "nameTaken": "Esse nome de integração não pode ser usado — já existe uma integração com esse identificador.", + "removeIcon": "Remover ícone", + "defaultIconNote": "Ícone padrão — envie um arquivo para usar o seu próprio." + }, + "toast": { + "created": "Integração criada", + "updated": "Integração atualizada", + "updateError": "Falha ao atualizar a integração" + }, + "delete": { + "title": "Excluir integração", + "confirm": "Excluir esta integração?", + "yes": "Excluir", + "no": "Cancelar", + "deleted": "Integração excluída", + "error": "Falha ao excluir a integração" + }, + "modules": { + "WINDOWS_AGENT": "Colete atividades do sistema Windows, segurança e logs de eventos por meio do agente leve UTMStack instalado em cada host.", + "LINUX_AGENT": "Colete logs de sistema, autenticação e auditoria do Linux por meio do agente leve UTMStack instalado em cada host.", + "MACOS": "Colete atividade de logs de sistema e segurança do macOS nos endpoints Apple Mac por meio do agente leve UTMStack.", + "VMWARE": "Ingira syslog do hipervisor VMware ESXi para que a atividade e os eventos do host de virtualização sejam monitorados no UTMStack.", + "NETFLOW": "Ingira registros NetFlow de roteadores e switches para monitorar padrões de tráfego de rede e detectar anomalias.", + "AWS_IAM_USER": "Ingira atividade de conta AWS e chamadas de API via CloudTrail e CloudWatch para auditar uso, acesso e alterações na nuvem.", + "AZURE": "Ingira logs de plataforma e atividade do Microsoft Azure para monitorar cargas de trabalho, identidade e alterações de recursos na nuvem.", + "O365": "Ingira logs de auditoria do Microsoft 365 no Exchange, Teams, SharePoint e OneDrive para monitorar a atividade de usuários e administradores.", + "O365_GRAPH": "Ingesta eventos de segurança do Microsoft Graph — alertas, incidentes, auditoria do diretório, sign-ins, detecções de risco e logs de auditoria do Purview — para monitorar identidade e atividade de ameaças no seu tenant.", + "GCP": "Ingira logs de auditoria e atividade do Google Cloud Platform para monitorar computação, armazenamento e identidade entre projetos.", + "KASPERSKY": "Ingira detecções e telemetria de endpoint do Kaspersky Security Center para correlacionar atividade de malware na rede.", + "ESET": "Ingira detecções e telemetria de endpoint do ESET PROTECT para correlacionar a defesa multicamadas contra malware em todo o ambiente.", + "BITDEFENDER": "Ingira detecções e telemetria de endpoint do Bitdefender GravityZone para correlacionar ameaças em dispositivos corporativos.", + "SENTINEL_ONE": "Ingira detecções de endpoint e telemetria comportamental do SentinelOne para correlacionar e investigar ameaças em escala.", + "SOPHOS": "Ingira detecções do Sophos Central em endpoint, servidor, firewall e e-mail para correlacionar ameaças em um único lugar.", + "CROWDSTRIKE": "Ingira detecções de endpoint e carga de trabalho do CrowdStrike Falcon para correlacionar atividade de ameaças nativas da nuvem no UTMStack.", + "CISCO": "Ingira logs de tráfego, VPN e ameaças do firewall Cisco ASA para monitorar a segurança de perímetro e o acesso no UTMStack.", + "MERAKI": "Ingira syslog do firewall e appliance de segurança Cisco Meraki para monitorar tráfego de rede e ameaças gerenciados na nuvem.", + "FIRE_POWER": "Ingira logs do NGFW e IPS Cisco Firepower para monitorar tentativas de intrusão e atividade de ameaças no perímetro.", + "CISCO_SWITCH": "Ingira syslog e telemetria de switches Cisco para monitorar desempenho de rede, alterações de configuração e segurança.", + "FORTIGATE": "Ingira logs de tráfego e ameaças do NGFW Fortinet FortiGate para monitorar a segurança de perímetro e a atividade de rede.", + "FORTIWEB": "Ingira logs do WAF Fortinet FortiWeb para monitorar ataques a aplicações web e proteger serviços e APIs expostos.", + "SOPHOS_XG": "Ingira logs do firewall Sophos XG com filtragem web, IPS e VPN para monitorar tráfego de rede e ameaças.", + "PALO_ALTO": "Ingira logs de tráfego e ameaças do NGFW Palo Alto Networks para monitorar o uso de aplicações e a segurança de perímetro.", + "SONIC_WALL": "Ingira logs de tráfego e ameaças do NGFW SonicWall para monitorar a segurança de perímetro e a atividade de rede no UTMStack.", + "PFSENSE": "Ingira logs de firewall e roteador do pfSense com gerenciamento unificado de ameaças para monitorar tráfego de rede e ameaças.", + "MIKROTIK": "Ingira logs de firewall, roteamento e wireless do MikroTik RouterOS para monitorar a atividade de rede e configurações.", + "AIX": "Colete logs de sistema, segurança e auditoria do IBM AIX Unix para monitorar a atividade em plataformas IBM Power no UTMStack.", + "AS_400": "Colete journals de sistema e auditoria do IBM AS/400 (IBM i) para monitorar a atividade de usuários em plataformas midrange OS/400.", + "ORACLE": "Ingira logs de auditoria do Oracle Database para monitorar consultas, acessos e atividade privilegiada nos bancos de dados.", + "SURICATA": "Ingira alertas e eventos de rede do Suricata IDS/IPS para detectar intrusões e tráfego malicioso na rede.", + "DECEPTIVE_BYTES": "Ingira alertas do Deceptive Bytes da sua plataforma ativa de decepção em endpoints para identificar atividade de atacantes precocemente.", + "GITHUB": "Ingira logs de auditoria do GitHub para monitorar acesso a repositórios, alterações de código e atividade da organização para segurança do código-fonte.", + "UTMSTACK": "Ingira a própria telemetria SIEM e XDR do UTMStack para monitorar a saúde da plataforma, atividade interna e eventos de autoauditoria.", + "NGINX": { + "name": "Nginx", + "description": "Ingira os logs de acesso e erro do Nginx para monitorar a atividade do servidor web, o tráfego do proxy reverso e as requisições dos clientes." + }, + "APACHE": { + "name": "Apache", + "description": "Ingira os logs de acesso e erro do Apache HTTPD para monitorar a atividade do servidor web e as requisições dos clientes." + }, + "APACHE2": { + "name": "Apache2", + "description": "Ingira os logs do servidor web Apache2 (HTTPD) para monitorar o processamento de requisições, erros e o acesso em hosts Linux." + }, + "IIS": { + "name": "IIS", + "description": "Ingira a atividade de acesso e os arquivos de log do Internet Information Services (IIS) para monitorar o serviço web do Windows." + }, + "MYSQL": { + "name": "MySQL", + "description": "Ingira a atividade de logs do MySQL para monitorar consultas, autenticação e o acesso ao repositório de dados." + }, + "POSTGRESQL": { + "name": "PostgreSQL", + "description": "Ingira os logs do PostgreSQL para monitorar consultas, acesso e a atividade em seus repositórios de dados." + }, + "MONGODB": { + "name": "MongoDB", + "description": "Ingira a atividade de logs do MongoDB para monitorar o acesso ao banco de dados documental, as consultas e o comportamento do aplicativo." + }, + "REDIS": { + "name": "Redis", + "description": "Ingira a atividade de logs e telemetria do Redis para monitorar o uso do repositório de dados em memória e as cargas de trabalho em tempo real." + }, + "ELASTICSEARCH": { + "name": "Elasticsearch", + "description": "Ingira os logs do Elasticsearch para monitorar o mecanismo de busca e análise e suas cargas de trabalho do aplicativo." + }, + "LOGSTASH": { + "name": "Logstash", + "description": "Ingira os logs das pipelines do Logstash para monitorar a pipeline de processamento de dados e suas transformações de eventos." + }, + "KIBANA": { + "name": "Kibana", + "description": "Ingira os logs do Kibana para monitorar a camada de visualização e exploração de dados e seu uso." + }, + "KAFKA": { + "name": "Apache Kafka", + "description": "Ingira os logs do Apache Kafka para monitorar as pipelines de streaming em tempo real, os brokers e o fluxo de mensagens." + }, + "NATS": { + "name": "NATS", + "description": "Ingira os logs de mensageria do NATS para monitorar o bus de mensagens, a conectividade e a entrega de eventos." + }, + "HAPROXY": { + "name": "HAProxy", + "description": "Ingira os logs do HAProxy para monitorar o balanceamento de carga, o tráfego do proxy e a disponibilidade da rede." + }, + "TRAEFIK": { + "name": "Traefik", + "description": "Ingira os logs do Traefik para monitorar o roteamento, o balanceamento de carga e o tráfego do proxy entre as cargas de trabalho." + }, + "OSQUERY": { + "name": "osquery", + "description": "Ingira os logs do OsQuery para monitorar o estado do endpoint, as consultas e o inventário do sistema por meio de requisições no estilo SQL." + }, + "SYSLOG": { + "name": "Syslog", + "description": "Envie syslog (RFC 5424/3164) de qualquer dispositivo ou aplicação para o endpoint do coletor, para a ingestão centralizada de logs." + }, + "JSON": { + "name": "JSON Input", + "description": "Envie cargas de logs em JSON para o endpoint de ingestão, para a captura estruturada de eventos de aplicativos e scripts." + }, + "WINDOWS_SQL_SERVER": { + "name": "SQL Server Event Logs", + "description": "Collect Microsoft SQL Server audit and event records through the Windows Event Log and UTMStack agent." + }, + "WINDOWS_FILE_AUDITING": { + "name": "Windows File Access Auditing", + "description": "Collect Windows file access audit events through the Windows Event Log and UTMStack agent." + }, + "ELASTICsearch": { + "name": "ELASTICsearch", + "description": "Ingesta los registros de Elasticsearch para monitorear el motor de búsqueda y análisis y sus cargas de trabajo de aplicación." + } + }, + "edit": { + "title": "Editar integração" + }, + "allCategories": "Todas as categorias", + "customOnly": "Personalizado" + }, + "dataProcessing": { + "title": "Processamento de dados", + "subtitle": "Estatísticas de ingestão e processamento: eventos recebidos, descartados por etapa, e as principais fontes e tipos.", + "ingestion": { + "title": "Ingestão", + "last24h": "últimas 24 horas", + "noData": "Sem dados nesta janela.", + "loadError": "Não foi possível carregar as estatísticas de ingestão.", + "groupBy": { + "dataSource": "Por fonte de dados", + "dataType": "Por tipo de dado" + }, + "status": { + "received": "Recebidos", + "parsing_dropped": "Descartados (parsing)", + "analysis_dropped": "Descartados (análise)", + "correlation_dropped": "Descartados (correlação)", + "all": "Todos os eventos" + } + }, + "filters": { + "title": "Filtros", + "new": "Novo filtro", + "search": "Pesquisar por caminho…", + "refresh": "Atualizar", + "retry": "Tentar novamente", + "empty": "Nenhum filtro corresponde.", + "loadError": "Não foi possível carregar os filtros.", + "toggleError": "Não foi possível alterar o estado do filtro", + "system": "Sistema", + "custom": "Personalizado", + "systemReadonly": "Os filtros do sistema são somente leitura", + "view": "Ver", + "edit": "Editar", + "ownership": { + "all": "Todos", + "system": "Sistema", + "custom": "Personalizados" + }, + "state": { + "all": "Todos", + "active": "Ativos", + "inactive": "Inativos" + }, + "col": { + "filter": "Filtro", + "type": "Tipo", + "active": "Ativo", + "actions": "Ações" + }, + "pageInfo": "{{from}}–{{to}} de {{count}}" + }, + "editor": { + "createTitle": "Novo filtro", + "editTitle": "Editar filtro", + "viewTitle": "Ver filtro", + "relPath": "Caminho", + "relPathHint": "Pasta + arquivo, ex. syslog/meu-filtro.yaml", + "content": "Pipeline (YAML)", + "contentHint": "As etapas rodam em ordem: grok, rename, delete, plugins dynamic, …", + "save": "Salvar", + "saving": "Salvando…", + "saved": "Filtro salvo", + "saveError": "Não foi possível salvar o filtro", + "cancel": "Cancelar", + "delete": "Excluir", + "deleteConfirm": "Excluir este filtro?", + "deleted": "Filtro excluído", + "deleteError": "Não foi possível excluir o filtro" + }, + "kpi": { + "received": "Recebidos", + "dropped": "Descartados", + "dropRate": "{{rate}}% de descarte", + "stored": "Armazenados", + "throughput": "Vazão", + "perMin": "{{value}}/min", + "survival": "{{rate}}% mantidos" + }, + "section": { + "overTime": "Eventos ao longo do tempo", + "top": "Top", + "dropReasons": "Motivos de descarte" + }, + "live": { + "auto": "Auto" + }, + "pipeline": { + "title": "Pipeline de ingestão", + "stages": { + "received": "Recebidos", + "parsed": "Analisados (parse)", + "analyzed": "Analisados", + "stored": "Armazenados" + } + }, + "chart": { + "title": "Vazão ao longo do tempo", + "received": "Recebidos", + "dropped": "Descartados" + }, + "donut": { + "title": "Composição de descartes", + "dropped": "descartados" + }, + "breakdown": { + "title": "Top fontes e tipos", + "bars": "Barras", + "treemap": "Treemap", + "showAll": "Ver todos os {{count}}", + "showLess": "Ver menos", + "lastSeen": "Visto por último", + "ago": "há {{time}}" + } }, - "refresh": { - "title": "Atualização automática", - "options": { - "off": "Desativado", - "10s": "10s", - "30s": "30s", - "1m": "1m", - "5m": "5m", - "15m": "15m" - } + "datasources": { + "limitBanner": { + "title": "Limite de datasources excedido.", + "message": "Você tem {{count}} datasources, mas sua licença cobre {{limit}}. Os logs dos datasources além do limite estão sendo descartados.", + "cta": "Gerenciar licença", + "dismiss": "Dispensar" + }, + "title": "Fontes de dados", + "total": "{{count}} no total", + "subtitle": "Agentes, integrações e fontes diretas que enviam eventos. O status é derivado da última vez que cada fonte foi vista.", + "connectSource": "Conectar uma fonte", + "loading": "Carregando fontes de dados…", + "loadFailed": "Não foi possível carregar as fontes de dados.", + "retry": "Tentar novamente", + "none": "Nenhuma fonte corresponde a esta visão.", + "ingestion": { + "title": "Ingestão", + "received": "eventos recebidos", + "none": "Sem ingestão nas últimas 24 horas.", + "ago24h": "há 24h", + "now": "agora" + }, + "usage": { + "title": "Fontes de dados", + "ofUnlimited": "de ilimitado", + "ofLimit": "de {{limit}}", + "overLimit": "Acima do limite licenciado — os dados além do limite estão em risco.", + "configured": "configuradas" + }, + "tabs": { + "all": "Todas", + "agent": "Agentes", + "puller": "Integrações", + "direct": "Diretas", + "offline": "Offline" + }, + "toolbar": { + "searchPlaceholder": "Buscar por nome…", + "list": "Lista", + "cards": "Cartões", + "refresh": "Atualizar" + }, + "labels": { + "filteredBy": "Filtrado por label", + "add": "Adicionar label…", + "addFirst": "Adicionar um label…", + "hint": "Digite um label e pressione Enter para adicioná-lo. As alterações são salvas automaticamente." + }, + "status": { + "live": "Ativa", + "idle": "Inativa", + "offline": "Offline" + }, + "kind": { + "agent": "Agente", + "puller": "Integração", + "direct": "Direta" + }, + "cols": { + "source": "Fonte", + "type": "Tipo", + "status": "Status", + "events24h": "Eventos 24h", + "lastSeen": "Visto por último" + }, + "time": { + "justNow": "agora mesmo", + "minutesAgo": "há {{count}}m", + "hoursAgo": "há {{count}}h", + "daysAgo": "há {{count}}d" + }, + "drawer": { + "loading": "Carregando…", + "loadFailed": "Não foi possível carregar a fonte de dados.", + "statsIdentity": "Stats e identidade", + "metadata": "Metadata", + "labelsSection": "Labels", + "dangerZone": "Zona de perigo", + "rows": { + "events24h": "Eventos 24h", + "lastSeen": "Visto por último", + "discovered": "Descoberta", + "kind": "Tipo de origem", + "dataType": "Tipo de dado", + "ip": "IP", + "id": "ID" + }, + "dangerText": "Excluir remove esta fonte do registro. Os eventos históricos continuam pesquisáveis no Log Explorer; se a fonte continuar enviando dados, será redescoberta.", + "delete": "Excluir fonte", + "confirmDelete": "Confirmar exclusão", + "cancel": "Cancelar", + "viewLogs": "Ver logs", + "trend": "Tendência de ingestão", + "noTrend": "Nenhum evento recebido nesta janela", + "logGap": "Último evento {{since}} — possível interrupção de logs" + }, + "toast": { + "labelsUpdated": "Labels atualizados", + "labelsFailed": "Falha ao atualizar os labels", + "deleted": "Fonte excluída", + "deleteFailed": "Falha ao excluir" + }, + "console": { + "section": "Console", + "sectionHint": "Execute comandos neste host através do seu agente (resposta ao vivo).", + "open": "Abrir console", + "close": "Fechar", + "hint": "Digite um comando e pressione Enter para executá-lo no agente.", + "running": "Executando…", + "placeholder": "Digite um comando…", + "offline": "Este agente parece estar offline — pode não responder aos comandos.", + "vars": { + "button": "Variáveis", + "title": "Variáveis de comandos", + "subtitle": "Use-as nos comandos como", + "add": "Nova variável", + "name": "Nome", + "value": "Valor", + "description": "Descrição", + "isSecret": "Secreto (criptografado, mascarado na saída)", + "secret": "secreto", + "secretHint": "Deixe em branco para manter o valor salvo.", + "save": "Salvar", + "cancel": "Cancelar", + "edit": "Editar", + "delete": "Excluir", + "loading": "Carregando…", + "empty": "Ainda não há variáveis.", + "saved": "Variável salva", + "deleted": "Variável excluída", + "nameRequired": "O nome é obrigatório", + "loadError": "Falha ao carregar as variáveis", + "saveError": "Falha ao salvar a variável", + "deleteError": "Falha ao excluir a variável", + "insert": "Inserir", + "valueRequired": "O valor é obrigatório" + }, + "disabled": "Agente offline — os comandos estão desabilitados", + "connError": "Erro de conexão", + "cmdError": "Erro de comando", + "shellSelect": "Tipo de shell", + "noRemoteControl": "Este agente foi instalado com o controlo remoto desativado. Recusa comandos, e isso só pode ser alterado na própria máquina.", + "noRemoteControlShort": "Controlo remoto desativado neste agente", + "password": { + "title": "Autenticação", + "hint": "Autentique-se para executar comandos neste agente.", + "tfaPrompt": "Código: ", + "confirm": "OK", + "cancel": "Cancelar", + "authError": "Falha na autenticação", + "authHint": "Autentique-se para executar comandos neste agente.", + "authOk": "Autenticado." + } + }, + "sensitivity": { + "section": "Sensibilidade do ativo", + "hint": "Criticidade de negócio (CIA, 0–3) deste ativo. Alertas direcionados ao seu host/IP são ponderados por esses valores.", + "saved": "Sensibilidade atualizada", + "failed": "Falha ao atualizar a sensibilidade", + "save": "Salvar", + "confidentiality": "Confidencialidade", + "integrity": "Integridade", + "availability": "Disponibilidade", + "levels": { + "0": "Nenhuma", + "1": "Baixa", + "2": "Média", + "3": "Alta" + } + }, + "health": { + "online": "online", + "offline": "offline", + "total": "total" + } }, - "editor": { - "editing": "Edição", - "addWidget": "Adicionar widget", - "save": "Salvar", - "discard": "Descartar", - "newTitle": "Novo widget", - "newSubtitle": "Escolha um tipo de gráfico, selecione uma fonte de dados e modele-o visualmente. O SQL é gerado automaticamente.", - "editTitle": "Editar widget", - "editSubtitle": "Ajuste a definição do gráfico. As alterações são aplicadas em todos os lugares em que este widget é usado.", - "loading": "Carregando widget…", - "notFoundTitle": "Widget não encontrado", - "notFoundSubtitle": "Pode ter sido excluída ou você não tem acesso a ela.", - "backToDashboard": "Voltar para o painel", - "chartType": { - "title": "Tipo de gráfico" - }, - "chartTypes": { - "bar": { - "label": "Barras", - "description": "Compare valores entre categorias." - }, - "line": { - "label": "Linha", - "description": "Tendências sobre um eixo ordenado." - }, - "area": { - "label": "Área", - "description": "Linha preenchida — destaca o volume." - }, - "pie": { - "label": "Pizza", - "description": "Proporção do total por categoria." - }, - "metric": { - "label": "Métrica", - "description": "Um único valor escalar." + "adversaries": { + "title": "Visão de adversários", + "subtitle": "Cada IP, host ou usuário visto atacando seu ambiente, com suas técnicas e alvos.", + "countChip": "{{count}} adversários", + "refresh": "Atualizar", + "search": "Pesquisar por IP, host, usuário, país, ASO…", + "empty": "Nenhum adversário corresponde.", + "loadError": "Não foi possível carregar os adversários.", + "retry": "Tentar novamente", + "views": { + "all": "Todos", + "high": "Severidade alta", + "ip": "IPs", + "host": "Hosts", + "user": "Usuários" }, - "table": { - "label": "Tabela", - "description": "Linhas agregadas." + "threat": { + "critical": "Crítico", + "high": "Alto", + "medium": "Médio", + "low": "Baixo" }, - "list": { - "label": "Lista", - "description": "Linhas brutas, sem agregação." + "kind": { + "ip": "IP", + "host": "Host", + "user": "Usuário" }, - "region_map": { - "label": "Mapa de coordenadas", - "description": "Posicione marcadores em um mapa-múndi usando coordenadas lat/lon." + "layout": { + "list": "Lista", + "cards": "Cartões" }, - "text": { - "label": "Texto", - "description": "Texto livre ou saída simples por linha." + "overview": { + "title": "Atividade de adversários · últimas 24 horas", + "high": "severidade alta", + "countries": "países", + "alerts": "alertas", + "ago24": "há 24h", + "ago12": "há 12h", + "now": "agora" + }, + "col": { + "adversary": "Adversário", + "threat": "Ameaça", + "alerts": "Alertas", + "targets": "Alvos", + "lastSeen": "Visto por último", + "victims": "Vítimas" + }, + "card": { + "alerts": "Alertas", + "techniques": "Técnicas", + "targets": "Alvos" + }, + "tabs": { + "profile": "Perfil", + "techniques": "Técnicas", + "targets": "Alvos", + "alerts": "Alertas" + }, + "drawer": { + "activity": "Atividade em 24 horas", + "identification": "Identificação", + "kindLabel": "Tipo", + "identifier": "Identificador", + "firstSeen": "Visto pela primeira vez", + "lastSeen": "Visto por último", + "geolocation": "Geolocalização", + "country": "País", + "city": "Cidade", + "topTechniques": "Principais técnicas", + "noTechniques": "Nenhuma técnica registrada.", + "targets": "Alvos", + "noTargets": "Nenhum alvo registrado.", + "recentAlerts": "Alertas recentes", + "noAlerts": "Sem alertas.", + "echoes": "{{count}} repetições" + }, + "relative": { + "justNow": "agora mesmo", + "minutesAgo": "há {{count}}m", + "hoursAgo": "há {{count}}h", + "daysAgo": "há {{count}}d" + }, + "field": { + "ip": "IP", + "host": "Host", + "user": "Usuário", + "port": "Porta", + "domain": "Domínio", + "mac": "MAC", + "country": "País", + "city": "Cidade", + "asn": "ASN", + "aso": "ASO" } - }, - "dataSource": { - "title": "Quais dados?", - "dataset": "Conjunto de dados", - "noDatasetHint": "Escolha um conjunto de dados para habilitar condições e agrupamento." - }, - "widgetTitle": { - "label": "Título", - "placeholder": "Opcional — padrão é o tipo de gráfico" - }, - "dataset": { - "placeholder": "Selecione um conjunto de dados…", - "loading": "Carregando conjuntos de dados…" - }, - "filters": { - "title": "Incluir apenas eventos onde…", - "empty": "Sem condições — todos os eventos do intervalo de tempo são incluídos.", - "add": "Adicionar condição", - "remove": "Remover", - "field": "Campo", - "fieldPlaceholder": "ex.: host.name", - "operator": "Operador", - "value": "Valor", - "valuePlaceholder": "Valor", + }, + "timeRange": { + "quick": "Intervalos rápidos", + "relative": "Relativo", + "absolute": "Absoluto", + "last": "Últimos", + "apply": "Aplicar", + "allTime": "Todo o tempo", "from": "De", "to": "Até", - "noValue": "Nenhum valor necessário", - "listPlaceholder": "Valores separados por vírgula" - }, - "operators": { - "IS": "é", - "IS_NOT": "não é", - "IS_ONE_OF_TERMS": "é um de", - "IS_GREATER_THAN": "é maior que", - "IS_LESS_THAN_OR_EQUALS": "é menor ou igual a", - "IS_BETWEEN": "está entre", - "CONTAIN": "contém", - "DOES_NOT_CONTAIN": "não contém", - "START_WITH": "começa com", - "ENDS_WITH": "termina com", - "EXIST": "existe", - "DOES_NOT_EXIST": "não existe" - }, - "dimension": { - "title": "Agrupar por", - "field": "Campo", - "placeholder": "Escolha um campo para agrupar…" - }, - "table": { - "hint": "Mostra todos os campos dos registros. Adicione colunas para escolher alguns.", - "columnsTitle": "Colunas", - "allColumns": "Todas as colunas serão exibidas. Adicione campos para escolher colunas específicas.", - "addColumn": "Adicionar uma coluna…", - "removeColumn": "Remover coluna" - }, - "chartPreview": { - "title": "Pré-visualização do gráfico", - "noQuery": "Escolha um conjunto de dados para ver a pré-visualização.", - "error": "A consulta de pré-visualização falhou." - }, - "chartTypeChip": { - "label": "Gráfico:" - }, - "chartTypeModal": { - "title": "Escolha um tipo de gráfico", - "subtitle": "Escolha como visualizar os dados. Você pode alterar isso depois.", - "confirm": "Continuar", - "swapTitle": "Alterar tipo de gráfico", - "swapConfirm": "Aplicar" - }, - "saveVisualization": "Salvar widget", - "fieldSelect": { - "loading": "Carregando campos…", - "choose": "Escolha um campo…" - }, - "toast": { - "notReady": "Escolha um conjunto de dados e um campo para detalhar antes de salvar." - }, - "breakdown": { - "title": "Detalhar por", - "topValuesTable": "Tabela de valores principais", - "time": "Ao longo do tempo", - "field": "Valores mais frequentes", - "interval": "Tamanho do intervalo", - "intervalAuto": "Automático", - "limit": "Quantos", - "limitPlaceholder": "Padrão (50)", - "splitHint": "Opcional: uma linha por valor deste campo." - }, - "editFilters": "Edit filters" - }, - "grid": { - "empty": "Este painel ainda não tem widgets.", - "missingVisualization": "Widget indisponível", - "unknownVisualization": "Widget" - }, - "widget": { - "renderError": "Não foi possível renderizar este widget.", - "count": "Contagem", - "loading": "Carregando dados…", - "queryError": "Não foi possível carregar os dados do widget.", - "noData": "Sem dados para o intervalo de tempo selecionado.", - "regionMapEmpty": "Nenhum ponto com lat/lon válidos.", - "regionMapShapeHint": "O SQL deve retornar colunas de latitude e longitude (ou um array value [lat, lon, count]).", - "regionMapUnnamed": "(sem nome)", - "regionMapValue": "valor: {{value}}", - "editAriaLabel": "Editar widget", - "removeAriaLabel": "Remover widget", - "moveBack": "Mover para trás", - "moveForward": "Mover para frente", - "width": "Largura", - "height": "Altura", - "widthSmall": "1 col", - "widthMedium": "2 cols", - "widthLarge": "3 cols", - "heightNormal": "Normal", - "heightTall": "Alto", - "incompleteSpec": "Falta parte da pergunta deste widget." - }, - "form": { - "createTitle": "Novo painel", - "renameTitle": "Editar painel", - "name": "Nome", - "namePlaceholder": "ex.: Visão geral da rede", - "description": "Descrição", - "descriptionPlaceholder": "Opcional", - "cancel": "Cancelar", - "create": "Criar", - "save": "Salvar" - }, - "confirm": { - "deleteTitle": "Excluir painel", - "delete": "Excluir o painel \"{{name}}\"? Esta ação não pode ser desfeita.", - "deleteWidgetsTitle": "Excluir widgets", - "deleteWidgets_one": "Excluir este widget? Esta ação não pode ser desfeita.", - "deleteWidgets_other": "Excluir {{count}} widgets? Esta ação não pode ser desfeita.", - "dismissTitle": "Remover painel", - "dismiss": "Remover o painel padrão \"{{name}}\"? Você poderá criar um novo a partir dele depois com \"Novo\" → \"De uma existente\"." - }, - "page": { - "noSelection": "Escolha um painel na lista ou crie um para começar.", - "loading": "Carregando widgets…" - }, - "toast": { - "created": "Painel criado.", - "createFailed": "Não foi possível criar o painel.", - "updated": "Painel atualizado.", - "updateFailed": "Não foi possível atualizar o painel.", - "deleted": "Painel excluído.", - "deleteFailed": "Não foi possível excluir o painel.", - "layoutSaved": "Layout salvo.", - "layoutSaveFailed": "Não foi possível salvar o layout.", - "visualizationCreated": "Widget criado.", - "visualizationCreateFailed": "Não foi possível criar o widget.", - "visualizationUpdated": "Widget atualizado.", - "visualizationUpdateFailed": "Não foi possível atualizar o widget.", - "visualizationDeleted": "Widget excluído.", - "visualizationDeleteFailed": "Não foi possível excluir o widget.", - "filterCreated": "Filtro criado.", - "filterUpdated": "Filtro atualizado.", - "filterDeleted": "Filtro excluído.", - "filterCreateFailed": "Não foi possível criar o filtro.", - "filterUpdateFailed": "Não foi possível atualizar o filtro.", - "filterDeleteFailed": "Não foi possível excluir o filtro.", - "filtersSaved": "Filters saved.", - "filtersSaveFailed": "Could not save filters." - }, - "newDashboard": { - "title": "Novo painel", - "subtitle": "Crie um painel em branco. Você pode adicionar widgets depois de salvá-lo.", - "modeManual": "Criar manualmente", - "modeAi": "Usando IA", - "aiLocked": "Ative o SOC-AI e configure-o para usar isso.", - "aiDescriptionLabel": "O que este painel deve mostrar?", - "aiDescriptionPlaceholder": "ex. Logins com falha por país, últimos 7 dias", - "aiCreate": "Criar com IA", - "aiOpenerWithDetails": "Crie um painel chamado \"{{name}}\" mostrando: {{description}}" + "now": "agora", + "units": { + "minutes": "minutos", + "hours": "horas", + "days": "dias", + "weeks": "semanas", + "months": "meses" + }, + "presets": { + "15m": "Últimos 15 minutos", + "1h": "Última hora", + "6h": "Últimas 6 horas", + "24h": "Últimas 24 horas", + "7d": "Últimos 7 dias", + "30d": "Últimos 30 dias" + } }, - "newVisualization": { - "title": "Novo widget", - "subtitle": "Defina um gráfico reutilizável a partir de uma consulta SQL e de uma configuração de ECharts.", - "sqlQuery": "Consulta SQL", - "sqlQueryPlaceholder": "SELECT bucket, count(*) FROM logs GROUP BY bucket", - "sqlQueryHint": "Use os marcadores timeFilter, from e to (entre chaves duplas) para que o seletor de tempo seja aplicado na renderização.", - "config": "Configuração do gráfico (opção do ECharts, JSON)", - "configHint": "Deve ser um JSON válido. As linhas do SQL ficam expostas como `dataset.source` — conecte suas séries com `encode`.", - "configError": "JSON inválido: {{error}}" + "socAi": { + "title": "Configuração do SOC-AI", + "subtitle": "Configure o agente de IA que faz triagem de alertas e alimenta o assistente de operações.", + "section": { + "connection": "Modelo e conexão", + "auth": "Autenticação", + "behavior": "Comportamento da triagem", + "advanced": "Avançado" + }, + "usage": { + "title": "Uso", + "chat": "Conclusões de chat (hoje)", + "unavailable": "O uso ainda não está disponível.", + "resetsIn": "Reinicia em {{time}}" + }, + "provider": { + "label": "Provedor", + "hint": "Define o formato. Qualquer um além do Anthropic usa a API compatível com OpenAI." + }, + "model": { + "label": "Modelo", + "hint": "Identificador do modelo do provedor.", + "customOption": "Modelo personalizado…", + "customPlaceholder": "Digite um ID de modelo" + }, + "url": { + "label": "URL da API", + "hint": "Deixe vazio para usar o endpoint padrão do provedor." + }, + "apiKey": { + "label": "Chave de API", + "hint": "Credencial enviada ao provedor.", + "setHint": "Há uma chave salva. Deixe em branco para mantê-la." + }, + "authType": { + "label": "Tipo de autenticação", + "hint": "Como as credenciais são enviadas ao seu gateway.", + "options": { + "apiKey": "API Key", + "bearer": "Bearer", + "customHeaders": "Cabeçalhos personalizados", + "none": "Nenhuma" + } + }, + "authHeaderName": { + "label": "Nome do cabeçalho de auth", + "hint": "Cabeçalho que carrega a chave (ex.: api-key para Azure)." + }, + "authToken": { + "label": "Token Bearer", + "hint": "Credencial enviada ao provedor.", + "setHint": "Um token está salvo. Deixe em branco para mantê-lo." + }, + "customHeaders": { + "label": "Cabeçalhos personalizados", + "hint": "Cabeçalhos extras enviados em cada requisição. Os valores são criptografados; \"*****\" mantém o salvo.", + "keyPlaceholder": "Nome do cabeçalho", + "valuePlaceholder": "Valor", + "addRow": "Adicionar cabeçalho", + "remove": "Remover cabeçalho" + }, + "maxTokens": { + "label": "Máx. tokens", + "hint": "Tokens máximos por resposta do LLM." + }, + "maxToolIterations": { + "label": "Máx. iterações de tools", + "hint": "Limite do loop planejar → tool → observar do agente." + }, + "autoAnalyze": { + "label": "Analisar alertas automaticamente", + "hint": "Faz triagem dos alertas recebidos em tempo real." + }, + "allowIncidents": { + "label": "Permitir gerenciar incidentes", + "hint": "O agente de triagem pode criar ou atualizar incidentes quando decide que um alerta o justifica." + }, + "changeAlertStatus": { + "label": "Alterar status do alerta", + "hint": "Permite ao agente definir o status de um alerta na triagem." + }, + "automaticIncidentCreation": { + "label": "Criar incidentes", + "hint": "Permite ao agente abrir incidentes a partir de alertas triados." + }, + "allowedWriteTools": { + "label": "Tools de escrita permitidas", + "hint": "Um nome de tool MCP por linha que o agente pode usar (ex.: alerts.update_status). Notas são sempre permitidas." + }, + "save": "Salvar configuração", + "saving": "Verificando e salvando…", + "saved": "Configuração do SOC-AI salva", + "saveError": "Falha ao salvar a configuração", + "loadError": "Falha ao carregar a configuração", + "modelRequired": "O modelo é obrigatório", + "applyTags": { + "label": "Aplicar tags", + "hint": "Permite ao agente marcar alertas com tags durante a triagem." + }, + "note": { + "azure": "Cole o endpoint completo do seu deployment do Azure como URL; o modelo é o nome do deployment. A auth usa o cabeçalho api-key.", + "ollama": "Aponte a URL para o seu host do Ollama. Não é necessária API key para uma instância local.", + "custom": "Qualquer endpoint compatível com OpenAI. Defina a URL, a auth e os cabeçalhos extras que seu gateway precisar.", + "threatwinds": "Usa sua licença UTMStack automaticamente — não precisa de API key. Cobrado através da sua assinatura ThreatWinds." + }, + "chat": { + "title": "Assistente SOC", + "dashboardCreateTitle": "Criador de painéis", + "empty": "Pergunte o que quiser sobre seus alertas, detecções ou o console — posso investigar e agir no SIEM.", + "tryPrefix": "Tente", + "suggestion": "quantos alertas abertos há, agrupados por adversário?", + "placeholder": "Digite uma pergunta…", + "ask": "Perguntar", + "send": "Enviar", + "collapse": "Recolher", + "expand": "Expandir", + "clear": "Limpar conversa", + "close": "Fechar", + "copy": "Copiar", + "copied": "Copiado", + "errorGeneric": "Algo deu errado.", + "errorUnreachable": "Não foi possível contatar o assistente.", + "compacting": "Compactando contexto…", + "dashboardEditTitle": "Editor de painéis", + "editingDashboard": "Editando: {{name}}", + "soarEditTitle": "Editor de fluxos SOAR", + "soarCreateTitle": "Criar fluxo SOAR", + "editingFlow": "Editando fluxo: {{name}}" + }, + "focus": { + "alert": "Alerta", + "incident": "Incidente", + "remove": "Parar de compartilhar com o assistente" + }, + "inheritance": { + "inherited": "Seguindo o padrão da instância. Salvar aqui dá a este tenant a própria configuração.", + "own": "Este tenant tem a própria configuração.", + "revert": "Voltar ao padrão da instância", + "reverting": "Revertendo…", + "reverted": "Agora segue o padrão da instância" + }, + "allowance": { + "title": "Consumo de IA hoje", + "ofLimit": "de {{limit}} requisições", + "denied": "requisições — a IA não está disponível para este tenant", + "hint": "Definido por quem opera a instância. Reinicia à meia-noite UTC." + } }, - "visualizationList": { - "title": "Widgets", - "subtitle": "{{count}} widget(s) disponível(eis).", - "subtitleFiltered": "Exibindo {{shown}} de {{total}}.", - "create": "Nova", - "searchPlaceholder": "Pesquisar widgets…", - "loading": "Carregando widgets…", - "empty": "Ainda não há widgets.", - "emptyFiltered": "Nenhum widget corresponde aos filtros atuais.", - "delete": "Excluir", - "deleteTitle": "Excluir widget", - "confirmDelete": "Excluir o widget \"{{name}}\"? Esta ação não pode ser desfeita.", - "filters": { - "search": "Pesquisar", - "chartType": "Tipo de gráfico", - "allChartTypes": "Todos os tipos de gráfico", - "source": "Fonte", - "allSources": "Todas as fontes", - "createdAt": "Criada", - "modifiedAt": "Modificada", - "createdRangeTitle": "Intervalo personalizado — Criação", - "modifiedRangeTitle": "Intervalo personalizado — Modificação", - "pickRange": "Escolher um intervalo", - "datePresets": { - "all": "Todo o período", - "today": "Hoje", - "last7": "Últimos 7 dias", - "last30": "Últimos 30 dias", - "lastYear": "Último ano", - "custom": "Intervalo personalizado" - }, - "clear": "Limpar filtros" - }, - "col": { - "name": "Nome", - "chartType": "Tipo de gráfico", - "source": "Fonte", - "description": "Descrição", - "created": "Criada", - "modified": "Modificada" - } - }, - "tabs": { - "dashboards": "Painéis", - "visualizations": "Widgets", - "newDashboard": "Novo painel", - "unsetDefault": "Remover padrão", - "options": "Opções" - }, - "picker": { - "none": "Selecionar painel", - "search": "Buscar painéis…", - "new": "Novo painel", - "setDefault": "Definir como padrão", - "empty": "Sem painéis" - }, - "empty": { - "title": "Ainda não há painéis", - "body": "Crie seu primeiro painel para ver seus dados de segurança rapidamente.", - "cta": "Criar painel" - }, - "filters": { - "addTitle": "Adicionar filtro", - "editTitle": "Editar filtro", - "removeTitle": "Remover filtro", - "removeConfirm": "Remover o filtro \"{{label}}\"? Esta ação não pode ser desfeita.", - "remove": "Remover", - "editAria": "Editar filtro", - "removeAria": "Remover filtro", - "saving": "Salvando…", - "addChip": "Adicionar filtro", - "chooseValue": "Choose…", - "selected": "selected", - "loading": "Loading values…", - "searchPlaceholder": "Search values…", - "noValues": "No values available.", - "loadError": "Could not load values.", - "clear": "Clear", - "editorTitle": "Dashboard filters", - "editorHint": "Add dropdown chips that filter every widget on this dashboard.", - "emptyEditor": "No filter chips yet. Add one to get started.", - "cancel": "Cancel", - "save": "Save", - "field": { - "dataset": "Data set", - "field": "Field", - "chooseField": "Choose a field…", - "label": "Label", - "labelPlaceholder": "e.g. Host", - "placeholder": "Placeholder", - "placeholderPlaceholder": "e.g. Pick a host", - "multiple": "Multiple", - "searchable": "Searchable" - } - }, - "duplicate": { - "copyName": "{{name}} (cópia)" - } - }, - "settings": { - "title": "Configurações", - "license": "Licença", - "notifications": "Notificações", - "connectionKey": "Chave de conexão", - "dataRetention": "Retenção de dados", - "indices": "Índices", - "theme": "Tema", - "branding": "Marca", - "apiKeys": "Chaves de API", - "identityProviders": "Provedores de identidade", - "email": "Configuração de e-mail", - "dateFormat": "Formato de data", - "language": "Idioma", - "auditLogs": "Logs de auditoria", - "about": "Sobre", - "socAi": "SOC-AI", - "supportAccess": "Acesso de suporte", - "threatwinds": "Integração ThreatWinds" - }, - "topbar": { - "theme": { - "light": "Modo claro", - "dark": "Modo escuro" - }, - "manageLicense": "Gerenciar licença", - "profile": { - "profile": "Perfil", - "license": "Licença", - "logout": "Sair" - } - }, - "notifications": { - "title": "Notificações", - "markAllRead": "Marcar todas como lidas", - "empty": "Você não tem notificações.", - "viewAll": "Ver todas", - "markRead": "Marcar como lida", - "markUnread": "Marcar como não lida", - "delete": "Excluir", - "subtitle": "{{total}} no total · {{unread}} não lidas", - "allCaughtUp": "Tudo em dia.", - "loadFailed": "Não foi possível carregar as notificações." - }, - "pagination": { - "perPage": "Por página", - "pageOf": "Página {{page}} de {{total}}", - "previous": "Anterior", - "next": "Próxima" - }, - "license": { - "title": "Licença", - "subtitle": "Sua edição, recursos e arquivo de licença.", - "loading": "Carregando licença…", - "loadError": "Não foi possível carregar as informações da licença.", - "statusLabel": "Status", - "status": { - "community": "Community", - "active": "Ativa", - "expiring": "A expirar", - "expired": "Expirada" - }, - "edition": "Edição", - "enterprise": "Enterprise", - "community": "Community", - "editionLine": "Edição {{edition}}", - "datasourceLimit": "Limite de fontes de dados", - "unlimited": "Ilimitado", - "mssp": "MSSP / multi-tenant", - "enabled": "Ativado", - "licenseType": "Tipo de licença", - "instanceId": "ID da instância", - "enterpriseUnlocked": "Recursos Enterprise desbloqueados", - "validUntil": "Válida até", - "noExpiry": "Sem expiração", - "timeRemaining": "Tempo restante", - "expiredAgo": "Expirou há {{days}}d", - "daysShort": "{{days}}d", - "msspShort": "MSSP", - "communityEdition": "Edição Community", - "communityBlurb": "Gratuita e de código aberto. Envie uma licença Enterprise abaixo para desbloquear multi-tenancy, SSO, limites maiores de fontes de dados e conformidade avançada.", - "upgrade": "Atualizar para Enterprise", - "uploadTitle": "Enviar uma licença", - "uploadBlurb": "Instale ou substitua o arquivo LICENSE assinado. O servidor valida a assinatura e a expiração antes de aplicá-lo. Apenas admin.", - "installLicense": "Instalar licença", - "chooseFile": "Escolher arquivo", - "noFileSelected": "Nenhum arquivo selecionado", - "toast": { - "installed": "Licença instalada — edição {{edition}}.", - "adminRequired": "São necessários privilégios de administrador para enviar uma licença.", - "invalid": "Arquivo de licença inválido ou expirado.", - "installFailed": "Não foi possível instalar a licença." - }, - "ingestLimit": "Volume de ingestão", - "notMetered": "Sem medição", - "gbPerMonth": "{{gb}} GB/mês" - }, - "audit": { - "title": "Log de auditoria", - "subtitle": "Registro de cada ação relevante para a segurança.", - "totalEntries": "{{total}} entradas no total.", - "loadError": "Não foi possível carregar o log de auditoria", - "stats": { - "totalEntries": "Entradas totais", - "acrossAllTime": "De todo o período", - "successRate": "Taxa de sucesso", - "failuresOnPage_one": "{{count}} falha nesta página", - "failuresOnPage_other": "{{count}} falhas nesta página", - "topAction": "Ação principal", - "onPage": "{{count}} nesta página", - "uniqueActors": "Atores únicos", - "includingSystem": "Incluindo o sistema" - }, - "filters": { - "title": "Filtros", - "clear": "Limpar", - "last24h": "Últimas 24h", - "failuresOnly": "Apenas falhas", - "authEvents": "Eventos de autenticação", - "actionPrefix": "Prefixo da ação", - "actionPlaceholder": "ex. auth., user.update", - "status": "Status", - "any": "Qualquer", - "resourceType": "Tipo de recurso", - "resourceTypePlaceholder": "user, alert…", - "resourceId": "ID do recurso", - "user": "Usuário", - "userPlaceholder": "login…" - }, - "statusValue": { - "success": "Sucesso", - "failure": "Falha" - }, - "table": { - "timestamp": "Data e hora", - "actor": "Ator", - "action": "Ação", - "resource": "Recurso", - "status": "Status", - "ip": "IP", - "loading": "Carregando…", - "emptyTitle": "Nenhuma entrada corresponde a estes filtros.", - "emptyHint": "Tente limpar os filtros ou ampliar o intervalo de datas.", - "system": "sistema", - "view": "Ver" - }, - "drawer": { - "entry": "entrada #{{id}}", - "overview": "Visão geral", - "raw": "JSON bruto", - "error": "Erro", - "actor": "Ator", - "resource": "Recurso", - "ip": "IP", - "userAgent": "Agente de usuário", - "session": "Sessão", - "metadata": "Metadados", - "copy": "Copiar", - "copied": "Copiado", - "copyJson": "Copiar JSON" - } - }, - "team": { - "title": "Equipe", - "subtitle": "Gerencie os usuários e suas funções.", - "tabs": { - "members": "Membros", - "roles": "Funções e permissões" - }, - "toast": { - "rolesLoadFailed": "Não foi possível carregar as funções", - "userLoadFailed": "Não foi possível carregar o usuário", - "rolesUpdated": "Funções atualizadas", - "userReactivated": "Usuário reativado", - "userDeactivated": "Usuário desativado", - "tfaReset": "Autenticação em duas etapas redefinida", - "invitationSent": "Convite enviado", - "loginOrEmailInUse": "Esse login ou e-mail já está em uso", - "invalidRequest": "Solicitação inválida", - "noPermission": "Você não tem permissão para fazer isso", - "userNotFound": "Usuário não encontrado", - "operationFailed": "A operação falhou", - "emailInUse": "Esse e-mail já está em uso", - "roleCreated": "Função criada", - "roleUpdated": "Função atualizada", - "roleDeleted": "Função excluída", - "roleNameInUse": "Já existe uma função com esse identificador", - "roleImmutable": "Funções de sistema não podem ser modificadas", - "permissionsLoadFailed": "Não foi possível carregar as permissões", - "localUserCreated": "Usuário local criado" - }, - "members": { - "searchPlaceholder": "Pesquisar por nome ou e-mail…", - "invite": "Convidar usuário", - "colUser": "Usuário", - "colRoles": "Funções", - "col2fa": "2FA", - "colStatus": "Status", - "loading": "Carregando usuários…", - "loadFailed": "Não foi possível carregar os usuários.", - "retry": "Tentar novamente", - "noSearchMatch": "Nenhum usuário corresponde à sua busca.", - "none": "Ainda não há usuários.", - "noRole": "nenhuma", - "on": "Sim", - "off": "Não", - "countLabel_one": "{{count}} usuário · página {{page}} de {{pages}}", - "countLabel_other": "{{count}} usuários · página {{page}} de {{pages}}", - "federated": "SSO" - }, - "status": { - "inactive": "Inativo", - "pendingPassword": "Senha pendente", - "active": "Ativo", - "pending": "Convite pendente", - "suspended": "Suspenso" - }, - "drawer": { - "createdBy": "criado por {{actor}}", - "loading": "Carregando…", - "profileTitle": "Perfil", - "profileSubtitle": "Apenas o usuário pode editar isto, no seu próprio perfil.", - "name": "Nome", - "username": "Usuário", - "email": "E-mail", - "language": "Idioma", - "accountTitle": "Conta", - "status": "Status", - "statusActive": "Ativo", - "statusInactive": "Inativo", - "tfa": "2FA", - "tfaEnabled": "Ativada", - "tfaNotConfigured": "Não configurado", - "resetTfa": "Redefinir", - "resetTfaHint": "Desativa o 2FA deste usuário para que ele reconfigure no próximo login", - "resetTfaConfirmTitle": "Redefinir a autenticação em duas etapas?", - "resetTfaConfirmBody": "Isso desativa o 2FA de {{name}}. Ela entrará apenas com a senha e poderá configurá-lo novamente no perfil.", - "resetTfaConfirm": "Redefinir 2FA", - "pendingPasswordNote": "Ainda usa a senha temporária (convite não concluído).", - "lastModified": "Modificado {{time}}", - "rolesTitle": "Funções", - "rolesSubtitle": "As funções concedem permissões de módulo. Um usuário pode ter mais de uma.", - "noRoleWarning": "Nenhuma função atribuída — o usuário não terá acesso a nenhum módulo.", - "deactivate": "Desativar", - "reactivate": "Reativar", - "waitingInvite": "Aguardando o usuário aceitar o convite.", - "cancel": "Cancelar", - "saving": "Salvando…", - "saveRoles": "Salvar funções", - "created": "criado {{time}}", - "pendingNote": "O convite ainda não foi aceito.", - "federatedNote": "Entra através de um provedor de identidade." - }, - "invite": { - "title": "Convidar usuário", - "description": "A conta é criada inativa. O usuário recebe um e-mail para definir sua senha e ativá-la.", - "username": "Usuário", - "usernameHint": "Pelo menos 3 caracteres.", - "email": "E-mail", - "firstName": "Nome", - "lastName": "Sobrenome", - "roles": "Funções", - "cancel": "Cancelar", - "sending": "Enviando…", - "send": "Enviar convite", - "name": "Nome", - "emailHint": "É o endereço com o qual fará login.", - "localDescription": "A conta é criada com uma senha e ativada imediatamente. Nenhum e-mail é enviado.", - "modeInvite": "Convidar usuário", - "modeLocal": "Criar usuário local", - "passwordLabel": "Senha", - "passwordPlaceholder": "Defina uma senha forte", - "localUserNote": "Este usuário não receberá um e-mail e será ativado automaticamente.", - "createLocal": "Criar usuário", - "passwordRules": { - "length": "Pelo menos 8 caracteres", - "case": "Pelo menos uma letra maiúscula e uma minúscula", - "special": "Pelo menos um caractere especial" - }, - "emailInvalid": "Insira um endereço de e-mail válido" - }, - "rolePicker": { - "none": "Nenhuma função disponível." - }, - "roles": { - "loading": "Carregando funções…", - "loadFailed": "Não foi possível carregar as permissões das funções.", - "readonlyNote": "As funções e suas permissões são definidas pelo sistema e são somente leitura. Atribua-as aos usuários na aba Membros.", - "permissionsCount_one": "{{count}} permissão", - "permissionsCount_other": "{{count}} permissões", - "modulesCount_one": "{{count}} módulo", - "modulesCount_other": "{{count}} módulos", - "matrixTitle": "Matriz de permissões", - "matrixSubtitle": "O que cada função pode fazer, por módulo.", - "permission": "Permissão", - "systemNote": "As funções de sistema vêm com a plataforma e não podem ser editadas. As que você criar pertencem a este tenant.", - "newRole": "Nova função", - "edit": "Editar", - "delete": "Excluir", - "systemBadge": "Sistema", - "createTitle": "Nova função", - "editTitle": "Editar função", - "editorSubtitle": "Escolha o que esta função pode fazer. Um usuário pode ter mais de uma.", - "nameLabel": "Identificador", - "nameHint": "Usado no código e na API. Por exemplo, ROLE_AUDITOR.", - "displayNameLabel": "Nome exibido", - "descriptionLabel": "Descrição", - "permissionsLabel": "Permissões", - "selectedCount": "{{count}} selecionadas", - "toggleAll": "todas", - "loadingPermissions": "Carregando permissões…", - "save": "Salvar função", - "deleteConfirmTitle": "Excluir esta função?", - "deleteConfirmBody": "{{name}} será removida. Quem tiver apenas esta função ficará sem acesso aos módulos." - }, - "langDefault": "Padrão do sistema", - "relative": { - "justNow": "agora mesmo", - "minutesAgo": "há {{count}} min", - "hoursAgo": "há {{count}} h", - "daysAgo": "há {{count}} d" - }, - "roleNames": { - "ROLE_ADMIN": "Administrador", - "ROLE_USER": "Usuário" - }, - "roleDescriptions": { - "ROLE_ADMIN": "Acesso total a todos os recursos", - "ROLE_USER": "Usuário padrão com acesso de leitura a nível de módulo" - }, - "actions": { - "read": "Leitura", - "write": "Escrita", - "delete": "Exclusão" - }, - "resources": { - "adaudit": "Auditoria AD", - "alerts": "Alertas", - "audit": "Registro de auditoria", - "compliance": "Conformidade", - "config": "Configuração", - "dashboards": "Painéis", - "datasources": "Datasources", - "eventprocessing": "Processamento de eventos", - "idp": "Provedores de identidade", - "incidents": "Incidentes", - "integrations": "Integrações", - "loganalyzer": "Analisador de logs", - "opensearch": "OpenSearch", - "roles": "Funções", - "soar": "SOAR", - "users": "Usuários", - "notifications": "Notificações", - "socai": "SOC AI", - "tenant": "Tenants", - "threatintel": "Inteligência de ameaças" - } - }, - "apiKeys": { - "title": "Chaves de API", - "subtitle": "Tokens de acesso programático para a API do UTMStack.", - "new": "Nova chave de API", - "searchPlaceholder": "Pesquisar por nome ou IP permitido…", - "refresh": "Atualizar", - "loading": "Carregando chaves de API…", - "loadFailed": "Não foi possível carregar as chaves de API.", - "retry": "Tentar novamente", - "noSearchMatch": "Nenhuma chave de API corresponde à sua pesquisa.", - "empty": "Ainda não há chaves de API. Crie uma para começar.", - "anyIp": "Qualquer IP", - "never": "Nunca", - "count_one": "{{count}} chave · página {{page}} de {{pages}}", - "count_other": "{{count}} chaves · página {{page}} de {{pages}}", - "enterprise": { - "title": "As chaves de API são um recurso Enterprise", - "body": "Emita, restrinja e rotacione chaves de API para acesso programático à API do UTMStack. Esse recurso está disponível na edição Enterprise.", - "upgrade": "Atualizar para Enterprise", - "manageLicense": "Gerenciar sua licença" - }, - "col": { - "name": "Nome", - "allowedIps": "IPs permitidos", - "created": "Criada", - "lastRotated": "Última rotação", - "expires": "Expira", - "status": "Status", - "actions": "Ações" - }, - "status": { - "active": "Ativa", - "expiring": "Expirando", - "expired": "Expirada" - }, - "action": { - "rotate": "Rotacionar", - "edit": "Editar", - "delete": "Excluir" - }, - "dialog": { - "editTitle": "Editar chave de API", - "newTitle": "Nova chave de API", - "name": "Nome", - "namePlaceholder": "ci-pipeline", - "allowedIps": "IPs permitidos", - "allowedIpsHint": "Separados por vírgula. Deixe vazio para permitir qualquer IP.", - "expires": "Expira", - "expiresHint": "Deixe vazio para uma chave que nunca expira.", - "secretNote": "O token secreto é mostrado uma única vez, logo após a criação. Copie-o então — não pode ser recuperado depois (apenas rotacionado).", - "cancel": "Cancelar", - "saving": "Salvando…", - "saveChanges": "Salvar alterações", - "createKey": "Criar chave" - }, - "confirm": { - "deleteTitle": "Excluir chave de API", - "rotateTitle": "Rotacionar chave de API", - "deleteBody": "Excluir {{name}}? Qualquer cliente que a utilize perderá o acesso imediatamente. Isso não pode ser desfeito.", - "rotateBody": "Rotacionar {{name}}? Um novo segredo é emitido e o atual para de funcionar imediatamente. O novo token é mostrado uma única vez.", - "cancel": "Cancelar", - "working": "Processando…", - "delete": "Excluir", - "rotate": "Rotacionar" - }, - "reveal": { - "title": "Chave de API criada", - "note": "Copie este segredo agora — para {{name}}. Ele não será mostrado novamente. Se você perdê-lo, rotacione a chave.", - "copied": "Copiado", - "copy": "Copiar", - "done": "Concluído" - }, - "toast": { - "updated": "Chave de API atualizada", - "secretIssueFailed": "Chave criada, mas o segredo não pôde ser emitido. Use Rotacionar para obter um.", - "deleted": "Chave de API excluída" - }, - "error": { - "nameTaken": "Já existe uma chave de API com esse nome", - "enterpriseRequired": "As chaves de API exigem a edição Enterprise", - "notFound": "Chave de API não encontrada", - "invalidRequest": "Solicitação inválida", - "failed": "Falha na operação" - } - }, - "idp": { - "title": "Provedores de identidade", - "subtitle": "Login único SAML 2.0 para sua organização.", - "add": "Adicionar provedor", - "enterprise": { - "title": "O SSO é um recurso Enterprise", - "body": "Conecte um provedor de identidade SAML 2.0 (Entra ID, Okta, Google Workspace…) para que sua equipe faça login com seu IdP. O login único está disponível na edição Enterprise.", - "upgrade": "Atualizar para Enterprise" - }, - "loading": "Carregando provedores de identidade…", - "loadFailed": "Não foi possível carregar os provedores de identidade.", - "retry": "Tentar novamente", - "empty": { - "title": "Nenhum provedor de identidade configurado", - "body": "Adicione um provedor SAML 2.0 para que sua equipe faça login com seu IdP corporativo." - }, - "card": { - "enable": "Ativar", - "disable": "Desativar", - "active": "Ativo", - "disabled": "Desativado", - "metadataUrl": "URL de metadados", - "spEntityId": "SP Entity ID", - "spAcsUrl": "SP ACS URL", - "loginUrl": "URL de login", - "copy": "Copiar", - "edit": "Editar", - "delete": "Excluir", - "jit": "Provisioning", - "jitOn": "creates accounts on first sign-in", - "sync": "Roles", - "syncOn": "re-applied on every sign-in" - }, - "form": { - "addTitle": "Adicionar provedor de identidade", - "editTitle": "Editar provedor de identidade", - "name": "Nome", - "nameHint": "Único. Usado na URL de SSO.", - "providerType": "Tipo de provedor", - "providerTypeHint": "Um rótulo, ex. azure, okta, google.", - "metadataUrl": "URL de metadados do IdP", - "spEntityId": "SP Entity ID", - "spAcsUrl": "SP ACS URL", - "certificate": "Certificado SP (PEM)", - "privateKey": "Chave privada SP (PEM)", - "privateKeyHintEdit": "Deixe vazio para manter a chave armazenada.", - "privateKeyHintCreate": "Obrigatória. Armazenada criptografada; não é exibida novamente.", - "privateKeyUnchanged": "•••••••• (inalterada)", - "active": "Ativo (mostrar na página de login)", - "cancel": "Cancelar", - "saving": "Salvando…", - "save": "Salvar alterações", - "create": "Criar provedor", - "issuer": "Issuer URL", - "issuerHint": "Discovery runs against this; the provider must serve /.well-known/openid-configuration under it.", - "clientId": "Client ID", - "redirectUrl": "Redirect URL", - "redirectUrlHint": "Register this exact URL with the provider.", - "host": "Host", - "port": "Port", - "startTls": "TLS", - "startTlsOn": "Use StartTLS", - "bindDn": "Bind DN", - "bindDnHint": "A service account that may search the directory.", - "baseDn": "Base DN", - "userFilter": "User filter", - "userFilterHint": "Must contain %s, where the address typed at login is placed.", - "emailAttribute": "Email attribute", - "nameAttribute": "Name attribute", - "groupAttribute": "Group attribute", - "provisioning": "Accounts and roles", - "provisioningHint": "What happens when someone the directory vouches for signs in.", - "jit": "Create the account on first sign-in", - "defaultRole": "Default role", - "defaultRoleHint": "Given when no group matches. Without one, an unmatched sign-in is refused.", - "noDefaultRole": "None", - "groupsAttribute": "Groups attribute", - "groupsAttributeHint": "Where the provider puts group membership.", - "syncRoles": "Re-apply roles on every sign-in", - "syncRolesHint": "Roles not in the mapping are removed, so a change in the directory reaches here. Without this, a demotion never arrives.", - "mappings": "Group to role", - "mappingsHint": "A directory group on the left, the role it grants on the right.", - "addMapping": "Add", - "noMappings": "No mappings. Everyone gets the default role.", - "groupPlaceholder": "SOC Analysts", - "pickRole": "Pick a role", - "secret.saml": "SP private key", - "secret.oidc": "Client secret", - "secret.ldap": "Bind password", - "secretHintCreate": "Stored encrypted and never shown again.", - "secretHintEdit": "Leave blank to keep the stored one.", - "secretUnchanged": "inalterado", - "errors": { - "required": "Este campo é obrigatório.", - "url": "Deve ser uma URL http(s) válida.", - "httpsUrl": "Deve ser uma URL https válida.", - "hostname": "Insira um host ou IP sem esquema (ex.: ldap.exemplo.com).", - "port": "A porta deve ser um número inteiro entre 0 e 65535.", - "pemCertificate": "Não parece um certificado PEM (falta -----BEGIN/END CERTIFICATE-----).", - "pemKey": "Não parece uma chave privada PEM (falta -----BEGIN/END PRIVATE KEY-----).", - "userFilterPlaceholder": "O filtro deve conter %s, onde é colocado o endereço de login.", - "userFilterUnbalanced": "Parênteses desbalanceados — a busca não retornará nada.", - "nameFormat": "Use letras, dígitos, pontos, hífens ou underscores (máx. 64). Ele aparece na URL de SSO, sem espaços.", - "redirectUrl": "Deve ser uma URL https válida ou uma URL http de loopback (localhost / 127.0.0.1 / [::1]).", - "entityId": "Deve ser uma URI válida, ex.: https://utmstack.example.com/sp." - } - }, - "delete": { - "title": "Excluir provedor de identidade", - "body": "Excluir {{name}}? Os usuários não poderão mais fazer login por ele. Isso não pode ser desfeito.", - "cancel": "Cancelar", - "deleting": "Excluindo…", - "confirm": "Excluir" - }, - "toast": { - "enabled": "Provedor ativado", - "disabled": "Provedor desativado", - "created": "Provedor de identidade criado", - "updated": "Provedor de identidade atualizado", - "deleted": "Provedor de identidade excluído", - "paidPlan": "O SSO SAML requer um plano pago", - "enterpriseRequired": "O SSO requer a edição Enterprise", - "notFound": "Provedor de identidade não encontrado", - "invalid": "Configuração inválida", - "failed": "A operação falhou" - }, - "providerType": { - "saml": "SAML 2.0", - "oidc": "OpenID Connect", - "ldap": "LDAP / Active Directory", - "comingSoon": "ainda não disponível" - } - }, - "userAuditor": { - "title": "Auditor de usuários", - "subtitle": "Contas do Active Directory observadas nos seus logs de segurança do Windows — descobertas a partir de eventos de criação, logon e exclusão.", - "export": "Exportar", - "accountsChip": "{{count}} contas", - "overview": { - "title": "Inventário de contas", - "active": "ativas", - "disabled": "desativadas", - "deleted": "excluídas", - "seen24h": "{{count}} vistas nas últimas 24 horas", - "byDomain": "Por domínio" - }, - "views": { - "all": "Todas as contas", - "windows": "Windows", - "linux": "Linux", - "active": "Ativas", - "disabled": "Desativadas", - "deleted": "Excluídas", - "service": "Contas de serviço", - "stale": "Inativas (30d+)" - }, - "searchPlaceholder": "Pesquisar por nome de conta ou SID…", - "allTenants": "Todos os tenants", - "filters": { - "add": "Adicionar filtro", - "clearAll": "Limpar tudo", - "filterValues": "Filtrar valores…", - "loadingValues": "Carregando valores…", - "noValues": "Nenhum valor encontrado.", - "pickValue": "Escolha um valor para adicionar o filtro.", - "empty": "(vazio)", - "cancel": "Cancelar", - "addBtn": "Adicionar" - }, - "filterFields": { - "status": "Status do ciclo de vida" - }, - "ops": { - "is": "é" - }, - "refresh": "Atualizar", - "layout": { - "list": "Lista", - "cards": "Cartões" - }, - "list": { - "account": "Conta", - "identity": "Identidade", - "sid": "SID", - "status": "Status", - "lastLogon": "Último logon", - "lastSeen": "Visto por último", - "tenant": "Tenant" - }, - "status": { - "active": "Ativa", - "disabled": "Desativada", - "deleted": "Excluída" - }, - "badge": { - "service": "serviço", - "stale": "inativa" - }, - "empty": "Nenhuma conta corresponde a esta visão.", - "loadError": "Não foi possível carregar as contas do AD.", - "retry": "Tentar novamente", - "card": { - "lastLogon": "Último logon" - }, - "pageInfo": "{{from}}–{{to}} de {{count}}", - "drawer": { - "tenantInline": "tenant {{id}}", - "serviceAccount": "conta de serviço", - "stale": "inativa 30d+", - "viewInLogs": "Ver eventos no Log Explorer", - "copySid": "Copiar SID", - "copyUid": "Copiar identidade", - "copied": "Copiado", - "identity": "Identidade", - "accountName": "Nome da conta", - "domain": "Domínio", - "hostname": "Hostname", - "sid": "SID", - "uidNumber": "UID", - "machineId": "ID da máquina", - "tenant": "Tenant", - "adStatus": "Status no AD", - "enabled": "Habilitada", - "disabled": "Desabilitada", - "lifecycle": "Ciclo de vida", - "created": "Conta criada", - "lastLogon": "Último logon", - "lastSeen": "Visto por último nos logs", - "deleted": "Conta excluída", - "noLifecycle": "Sem eventos de ciclo de vida." - }, - "relative": { - "justNow": "agora mesmo", - "minutesAgo": "há {{count}}m", - "hoursAgo": "há {{count}}h", - "daysAgo": "há {{count}}d" - }, - "none": "—" - }, - "connectionKey": { - "title": "Chave de conexão", - "subtitle1": "A chave que os agentes apresentam ao se registrar nesta instância.", - "subtitleEmphasis": "É usada apenas para a instalação de agentes", - "subtitle2": "— não para coletores, integrações ou a API. É gerenciada pelo agent-manager.", - "status": { - "label": "Status", - "loading": "Carregando…", - "unavailable": "Agent-manager indisponível", - "active": "Ativa", - "unavailableHint": "Não foi possível contatar o agent-manager para ler a chave.", - "activeHint": "Os agentes podem se registrar com esta chave." - }, - "token": { - "title": "Chave de conexão", - "subtitle": "Trate este valor como uma credencial. Rotacioná-la emite uma nova chave para futuras instalações de agentes — os agentes já registrados continuam funcionando.", - "loadFailedTitle": "Não foi possível carregar a chave de conexão", - "unavailableTitle": "Chave de conexão indisponível", - "loadFailedHint": "A chave é gerenciada pelo agent-manager, que não respondeu. Tente novamente em instantes.", - "retry": "Tentar novamente", - "show": "Mostrar chave", - "hide": "Ocultar chave", - "copy": "Copiar", - "copied": "Copiado", - "regenerate": "Regenerar chave de conexão", - "confirmTitle": "Regenerar a chave?", - "confirmBody": "As novas instalações de agentes precisarão da nova chave. Os agentes já registrados continuam funcionando. Não há como desfazer.", - "regenerating": "Regenerando…", - "confirmYes": "Sim, regenerar", - "cancel": "Cancelar" - }, - "security": { - "title": "Recomendações de segurança", - "subtitle": "Boas práticas para proteger esta credencial.", - "rotateTitle": "Rotacione a cada 90 dias", - "rotateBody": "Agende uma rotação recorrente. O UTMStack pode enviar um lembrete por e-mail quando a chave tiver mais de 90 dias.", - "rotateAction": "Configurar lembrete", - "secretTitle": "Armazene como segredo", - "secretBody": "Não faça commit no controle de versão. Use seu gerenciador de segredos (Vault, AWS SM, etc.) e injete-a no momento da instalação.", - "auditTitle": "Audite quem a obteve", - "auditBody": "Cada obtenção e rotação é registrada no log de auditoria da aplicação.", - "auditAction": "Ver log de auditoria" - }, - "toast": { - "loadFailed": "Não foi possível carregar a chave de conexão", - "rotated": "Chave de conexão rotacionada", - "rotateFailed": "Não foi possível rotacionar a chave de conexão", - "copyFailed": "Não foi possível copiar" - } - }, - "dataRetention": { - "title": "Retenção de dados", - "subtitle": "How long each dataset is kept, and when its records stop costing local disk.", - "loading": "Carregando…", - "loadFailed": "Could not read the store.", - "retry": "Tentar novamente", - "datasets": { - "logs": "Logs", - "alerts": "Alerts", - "statistics": "Ingestion statistics" - }, - "holding": "{{documents}} records · {{size}}", - "since": "since {{date}}", - "diskUsed": "Disk {{pct}}% used", - "keep": "Delete after", - "keepHint": "A record is deleted this many days after it happened, wherever it is stored by then.", - "cold": "Move to cold storage after", - "coldHint": "Older records move to object storage and stay queryable. 0 keeps everything on local disk.", - "coldUnavailable": "Set up cold storage below to move older records off local disk.", - "coldBeforeDelete": "Records have to move before they are deleted: use fewer days than the lifetime, or 0.", - "tieredNote": "This dataset moves records to cold storage. Going back to local-only needs the table rebuilt, so it cannot be turned off here.", - "days": "dias", - "save": "Salvar", - "saving": "Salvando…", - "toast": { - "saved": "Retention saved", - "noPermission": "You do not have permission to change retention", - "saveFailed": "Could not save the retention" - }, - "coldStorage": { - "title": "Cold storage", - "hint": "An object store the event store treats as a second, slower disk. Older records move there and are still queried from the same place — it is not an archive and nothing has to be restored.", - "active": "In use", - "inactive": "Not set up", - "writtenNotReady": "The bucket is configured but the store has not picked it up. Check that the deployment shares the store's configuration directory.", - "endpoint": "Bucket URL", - "accessKey": "Access key", - "secretKey": "Secret key", - "bucketLocked": "The credentials can be changed at any time. The bucket cannot, once records live in it: the parts already moved carry it.", - "enable": "Enable cold storage", - "update": "Update credentials", - "toast": { - "saved": "Cold storage configured", - "failed": "Could not configure cold storage" - }, - "kind": "Tipo", - "kind_s3": "Armazenamento de objetos compatível com S3", - "kind_local": "Pasta local ou NFS", - "kind_azure": "Azure Blob Storage", - "accountUrl": "URL da conta de armazenamento", - "container": "Contêiner", - "accountName": "Nome da conta", - "accountKey": "Chave da conta", - "useRole": "Usar a função IAM do servidor em vez de chaves", - "s3Hint": "Funciona com AWS S3 e qualquer armazenamento compatível com S3: MinIO, Ceph, Wasabi, Cloudflare R2 ou Google Cloud Storage (endpoint https://storage.googleapis.com// com chaves HMAC).", - "localHint": "Os registros vão para a pasta montada em /mnt/utmstack-cold dentro do armazenamento de eventos: um diretório comum na pasta de dados, ou um compartilhamento NFS montado no host sobre /clickhouse/cold antes de iniciar o stack. Não exige credenciais.", - "changeWarning": "Records already moved to the current destination are not migrated. They stay there and stop being readable from here until the old destination is copied across by hand." - }, - "forbidden": { - "title": "Esta página é da plataforma", - "body": "A retenção se aplica às tabelas que todos os tenants compartilham, então só um administrador da plataforma pode lê-la ou alterá-la." - } - }, - "languageSettings": { - "title": "Idioma da plataforma", - "subtitle": "Idioma padrão para as telas de pré-login, e-mails do sistema e novos usuários. Cada usuário ainda pode escolher o seu no perfil.", - "label": "Idioma padrão", - "hint": "Usado quando um usuário não escolheu o próprio idioma.", - "save": "Salvar", - "saving": "Salvando…", - "saved": "Idioma da plataforma atualizado", - "loadError": "Não foi possível carregar a configuração de idioma", - "saveError": "Não foi possível salvar a configuração de idioma" - }, - "branding": { - "title": "Marca", - "subtitle": "Personalize o UTMStack com a identidade da sua organização — aplicado em tudo: tela de login, menu lateral, e-mails e relatórios.", - "enterpriseRequired": "O white-label é um recurso Enterprise.", - "manageLicense": "Gerenciar licença", - "enable": { - "title": "White-label", - "description": "Substitua a marca UTMStack pela sua em toda a plataforma.", - "label": "Ativar white-label" - }, - "identity": { - "title": "Identidade", - "productName": "Nome do produto", - "productNameHint": "Exibido na barra de título, menu lateral e e-mails.", - "accent": "Cor de destaque", - "accentHint": "Cor primária de botões, links e estados ativos.", - "custom": "Cor personalizada" - }, - "logos": { - "title": "Logos", - "hint": "PNG, SVG, WEBP, JPG ou ICO. Até 5 MB.", - "logo": "Logo (claro)", - "logoDark": "Logo (escuro)", - "favicon": "Favicon" - }, - "reports": { - "title": "Recursos de relatório", - "hint": "Incorporados nos relatórios PDF gerados.", - "reportLogo": "Logo do relatório", - "reportCover": "Capa do relatório" - }, - "asset": { - "upload": "Enviar", - "replace": "Substituir" - }, - "save": "Salvar alterações", - "saving": "Salvando…", - "saved": "Marca atualizada", - "saveError": "Não foi possível salvar a marca", - "uploaded": "Imagem enviada", - "uploadError": "Não foi possível enviar a imagem", - "loadError": "Não foi possível carregar a marca", - "enterprise": { - "title": "A marca branca é um recurso Enterprise", - "body": "Substitua o nome do produto, o logotipo e a capa dos relatórios pelos seus, para que o painel e tudo o que ele gera levem a sua marca e não a da UTMStack.", - "upgrade": "Atualizar para Enterprise" - }, - "restore": "Restaurar os padrões da UTMStack", - "restored": "Marca restaurada aos padrões da UTMStack" - }, - "emailConfig": { - "title": "Configuração de e-mail", - "subtitle": "Servidor SMTP usado para enviar notificações de alertas, relatórios e e-mails de conta.", - "server": { - "title": "Servidor SMTP", - "host": "Host", - "hostHint": "Nome do servidor SMTP.", - "port": "Porta", - "encryption": "Criptografia", - "username": "Usuário", - "password": "Senha", - "passwordSetHint": "Há uma senha salva. Deixe em branco para mantê-la ou digite uma nova para alterá-la." - }, - "encryptionOpt": { - "TLS": "TLS", - "SSL": "SSL", - "NONE": "Nenhuma" - }, - "sender": { - "title": "Remetente", - "from": "Endereço de origem", - "fromHint": "Endereço a partir do qual os e-mails são enviados.", - "organization": "Nome da organização", - "organizationHint": "Exibido nos e-mails de notificação de alertas e incidentes.", - "baseUrl": "URL base", - "baseUrlHint": "URL pública desta instância, usada nos links dos e-mails." - }, - "test": { - "button": "Enviar teste", - "sending": "Enviando…", - "sentTo": "Um e-mail de teste será enviado para {{email}}.", - "success": "E-mail de teste enviado para {{email}}", - "fail": "Não foi possível enviar o e-mail de teste", - "fromRequired": "Defina um endereço de origem antes de testar" - }, - "save": "Salvar alterações", - "saving": "Salvando…", - "saved": "Configuração de e-mail salva", - "saveError": "Não foi possível salvar a configuração", - "loadError": "Não foi possível carregar a configuração", - "recipients": { - "alertsTitle": "Destinatários de alertas", - "incidentsTitle": "Destinatários de incidentes", - "to": "Para", - "cc": "CC", - "alertsHelper": "Endereços avisados quando novos alertas são gerados. Se deixar vazio, os alertas não são enviados por email.", - "incidentsHelper": "Endereços avisados quando um incidente é criado. Se deixar vazio, os incidentes não são enviados por email.", - "add": "Adicionar" - } - }, - "dateFormat": { - "title": "Data e hora", - "subtitle": "Como os timestamps são exibidos em toda a plataforma. Os logs são sempre armazenados em UTC.", - "timezone": { - "title": "Fuso horário", - "hint": "Os timestamps são exibidos neste fuso horário. Os dados são armazenados em UTC.", - "system": "Padrão do navegador", - "now": "Agora: {{value}}" - }, - "format": { - "title": "Formato de data", - "hint": "Estilo usado para datas e horas." - }, - "styles": { - "short": "Curto", - "medium": "Médio", - "long": "Longo", - "full": "Completo" - }, - "save": "Salvar alterações", - "saving": "Salvando…", - "saved": "Configurações de data salvas", - "saveError": "Não foi possível salvar as configurações", - "loadError": "Não foi possível carregar as configurações" - }, - "about": { - "title": "Sobre esta instância", - "subtitle": "Versão, licença e saúde do sistema deste deployment do UTMStack.", - "loading": "Carregando informações da instância…", - "edition": { - "enterprise": "Enterprise", - "community": "Community" - }, - "fields": { - "hostname": "Servidor", - "instanceId": "ID da instância", - "noInstanceMeta": "Nenhum metadado da instância disponível." - }, - "license": { - "title": "Licença", - "enterpriseMssp": "Enterprise · MSSP", - "datasources": "Datasources", - "communityLimited": "Limite Community", - "unlimited": "Ilimitado", - "expires": "Expira", - "managedNote": "Edição, limites de datasources e upload de licença são gerenciados na página de Licença.", - "view": "Ver licença", - "ingest": "Volume de ingestão", - "notMetered": "Sem medição", - "gbPerMonth": "{{gb}} GB/mês" - }, - "services": { - "backend": { - "name": "Backend API", - "desc": "Gateway REST, autenticação e orquestração de módulos." - }, - "opensearch": { - "name": "OpenSearch", - "desc": "Armazenamento de logs e eventos.", - "detail": "{{nodes}} nós · {{shards}} shards" - }, - "unreachable": "Inacessível" - }, - "status": { - "up": "Saudável", - "degraded": "Degradado", - "down": "Fora do ar", - "unknown": "Desconhecido" - }, - "health": { - "title": "Saúde do sistema", - "allHealthy": "Todos os serviços saudáveis. Atualize para verificar.", - "issues_one": "{{count}} serviço precisa de atenção.", - "issues_other": "{{count}} serviços precisam de atenção.", - "refresh": "Atualizar" - }, - "usage": { - "title": "Fontes de dados", - "subtitle": "Fontes de dados configuradas nesta instalação.", - "ofUnlimited": "de ilimitado", - "ofLimit": "de {{limit}}", - "overLimit": "Acima do limite licenciado — os dados além do limite estão em risco.", - "configured": "configuradas" - }, - "support": { - "title": "Suporte", - "docs": "Documentação", - "repo": "Repositório no GitHub", - "issues": "Relatar um problema", - "website": "utmstack.com" - }, - "legal": { - "title": "Legal", - "license": "Licença", - "security": "Divulgação de segurança", - "copyright": "© {{year}} UTMStack. Todos os direitos reservados." - } - }, - "logExplorer": { - "title": "Explorador de logs", - "eventsIn": "eventos em", - "searching": "Buscando…", - "query": { - "allDataTypes": "Todos os tipos de dados", - "dataTypes": "Tipos de dados", - "exportCsv": "Exportar CSV", - "filterDataTypes": "Filtrar tipos de dados…", - "noDataTypes": "Sem tipos de dados", - "noDataTypesMatch": "Nenhum tipo de dados corresponde", - "noTextSearch": "Esta origem não tem campo de texto completo — filtre por campo", - "refresh": "Atualizar", - "run": "Executar", - "search": "Pesquisar", - "searchPlaceholder": "Buscar em todos os campos…" - }, - "time": { - "15m": "Últimos 15 minutos", - "1h": "Última hora", - "6h": "Últimas 6 horas", - "24h": "Últimas 24 horas", - "7d": "Últimos 7 dias", - "30d": "Últimos 30 dias" - }, - "ops": { - "is": "é", - "isNot": "não é", - "contains": "contém", - "exists": "existe", - "between": "entre", - "search": "busca", - "isOneOf": "é um de", - "isNotOneOf": "não é nenhum de", - "doesNotContain": "no contiene", - "startsWith": "empieza con", - "doesNotStartWith": "no empieza con", - "endsWith": "termina con", - "doesNotEndWith": "no termina con", - "doesNotExist": "no existe", - "notBetween": "no está entre", - "greaterThan": "es mayor que", - "greaterThanOrEquals": "es mayor o igual que", - "lessThan": "es menor que", - "lessThanOrEquals": "es menor o igual que" - }, - "filters": { - "label": "Filtros", - "clearAll": "Limpar tudo" - }, - "fields": { - "title": "Campos", - "filterPlaceholder": "Filtrar campos…", - "none": "Sem campos", - "selected": "Campos selecionados", - "available": "Campos disponíveis", - "topValues_one": "Top {{count}} valor", - "topValues_other": "Top {{count}} valores", - "loading": "Carregando…", - "noValues": "Sem valores", - "addColumn": "Adicionar como coluna", - "removeColumn": "Remover coluna da tabela", - "filterFor": "Filtrar pelo valor", - "filterOut": "Excluir o valor", - "empty": "(vazio)" - }, - "results": { - "dataTypesFailed": "Não foi possível carregar os tipos de dados.", - "endOfResults": "Todos os {{count}} eventos carregados", - "loadingMore": "Carregando mais…", - "message": "Mensagem", - "none": "Nenhum log corresponde a esta consulta.", - "removeColumn": "Remover {{field}}", - "retry": "Tentar novamente", - "searchFailed": "A busca falhou.", - "searching": "Buscando…", - "source": "Origem", - "time": "Hora", - "scope": "Pesquisado em {{dataset}} · {{dataType}}.", - "searchAllDataTypes": "Pesquisar todos os tipos" - }, - "detail": { - "fieldsCount_one": "{{count}} campo", - "fieldsCount_other": "{{count}} campos", - "copyJson": "Copiar JSON", - "copied": "Documento copiado", - "parsedFields": "Campos analisados", - "json": "JSON", - "filterFor": "Filtrar por", - "filterOut": "Excluir", - "surrounding": "Eventos ao redor", - "surroundingHint": "Mostrar eventos ±15 min ao redor deste, da mesma fonte" - }, - "view": { - "table": "Tabela", - "chart": "Gráfico" - }, - "chart": { - "aggregateOn": "Agregar por", - "per": "a cada", - "topValues": "— top 20 valores", - "building": "Construindo gráfico…", - "failed": "Não foi possível construir o gráfico para este campo.", - "noData": "Sem dados para o gráfico." - }, - "intervals": { - "minute": "Minuto", - "hour": "Hora", - "day": "Dia", - "week": "Semana", - "month": "Mês", - "quarter": "Trimestre", - "year": "Ano" - }, - "toast": { - "exportFailed": "A exportação falhou" - }, - "builder": { - "add": "Adicionar filtro", - "filterValues": "Filtrar valores…", - "loadingValues": "Carregando valores…", - "noValues": "Sem valores.", - "cancel": "Cancelar", - "confirm": "Adicionar", - "pickValue": "Pick a value to add the filter." - }, - "related": { - "nLogs_one": "{{count}} log", - "nLogs_other": "{{count}} logs", - "truncated": "Mostrando os primeiros {{count}} logs relacionados (o conjunto completo é maior)." - }, - "saved": { - "title": "Salvas", - "empty": "Ainda não há buscas salvas", - "saveCurrent": "Salvar busca atual", - "save": "Salvar", - "namePlaceholder": "Nome da busca", - "delete": "Excluir", - "saved": "Salva “{{name}}”", - "loading": "Carregando…", - "loadFailed": "Não foi possível carregar as buscas salvas", - "saveFailed": "Não foi possível salvar a busca", - "deleteFailed": "Não foi possível excluir a busca", - "unreadable": "Não foi possível ler essa busca salva" - } - }, - "integrations": { - "title": "Integrações", - "searchPlaceholder": "Pesquisar integrações…", - "noMatch": "Nenhuma integração corresponde.", - "browseMarketplace": "Explorar marketplace", - "loading": "Carregando integrações…", - "addCustom": { - "title": "Adicionar integração personalizada", - "description": "Criar uma nova fonte personalizada", - "cta": "Criar" - }, - "tabs": { - "all": "Todas", - "agents": "Agentes", - "collectors": "Coletores", - "cloud": "Cloud", - "custom": "Personalizada" - }, - "kind": { - "agents & syslog": "Agente", - "device": "Coletor", - "antivirus": "Coletor", - "other": "Coletor", - "custom": "Personalizada", - "cloud": "Cloud", - "utmstack modules": "Coletor" - }, - "status": { - "configured": "Configurada", - "available": "Disponível" - }, - "card": { - "manage": "Gerenciar →", - "setup": "Configurar →", - "eventsPerSec": "{{rate}} e/s", - "enabled": "Ativado", - "setupShort": "Configurar" - }, - "drawer": { - "manage": "Gerenciar", - "openDashboard": "Abrir painel", - "viewEvents": "Ver eventos", - "documentation": "Documentação", - "getInstallCmd": "Obter comando de instalação", - "setupCollector": "Configurar coletor", - "connect": "Conectar", - "configureCustom": "Configurar fonte personalizada", - "eventsRate": "{{rate}} eventos/s · {{count}} em 24h", - "manageRules": "Regras", - "manageFilters": "Filtros" - }, - "setup": { - "agent": { - "howItWorksTitle": "Como funciona", - "howItWorksBody": "O agente {{name}} é um pequeno daemon que executa no host e encaminha eventos locais para o UTMStack através de uma conexão TLS autenticada. Ele se atualiza automaticamente e relata sua saúde.", - "installTitle": "Instalar em {{name}}", - "installHint": "Execute este comando em cada host {{name}} que deseje monitorar. O token já codifica seu workspace atual.", - "afterTitle": "O que você verá após a instalação", - "after1": "O host aparece em Fontes de dados dentro de ~60 segundos após o início do agente.", - "after2": "A telemetria começa a fluir para o Log Explorer, limitada ao seu workspace.", - "after3": "O agente auto-relata CPU / memória / saúde do disco para o UTMStack.", - "actionLabel": "Ação", - "platformLabel": "Plataforma", - "optionsLabel": "Opções", - "skipCertValidation": "Não validar o certificado TLS (servidor autoassinado)", - "noRemoteControl": "Desativar a execução remota de comandos neste host", - "loadingToken": "Carregando token…", - "actions": { - "install": "Instalar", - "uninstall": "Desinstalar" - }, - "prereqTitle": "Requisitos de pré-instalação", - "prereqBody": "O agente UTMStack se comunica com o servidor pelas portas abaixo. Certifique-se de que estejam abertas entre o host e o UTMStack antes de instalar:", - "sensitiveWarning": "O comando abaixo contém um token de registro sensível — não o compartilhe.", - "uninstall": { - "title": "Desinstalar o agente", - "body": "Execute este comando no host para parar e remover o agente UTMStack e seus serviços. Utiliza a plataforma selecionada acima." - }, - "macCompat": "Requer macOS 11 (Big Sur) ou superior em Apple Silicon (M1/M2/M3 ou mais recente). Macs com Intel não são suportados." - }, - "collector": { - "howItWorksTitle": "Como funciona", - "howItWorksBody": "{{name}} não executa um agente do UTMStack. Em vez disso, você instala o coletor do UTMStack em algum lugar da rede que tanto seu dispositivo {{name}} quanto o UTMStack possam acessar. {{name}} envia syslog para o coletor, o coletor analisa, normaliza e encaminha eventos para o UTMStack.", - "step1Title": "1 · Instalar o coletor do UTMStack", - "step1Hint": "Execute em um host Linux com acesso de rede do dispositivo {{name}}.", - "step2Title": "2 · Configurar {{name}} para enviar syslog", - "step2Hint": "No dispositivo {{name}}, aponte o encaminhamento de syslog para o endereço do coletor em {{port}}.", - "vendorDocs": "Ver instruções específicas do fornecedor", - "step3Title": "3 · Verificar", - "step3Body": "Dentro de alguns minutos você deve ver eventos de {{name}} em source: {{source}} no Log Explorer, e uma nova entrada em Fontes de dados.", - "forwarder": { - "intro": { - "title": "Como funciona", - "body": "Os registros fluem de {{source}} para o UTMStack Collector, que os transmite com segurança ao UTMStack para correlação e alertas. Nada é instalado em {{source}} — apenas o Collector precisa ser executado em um host na sua rede." - }, - "diagram": { - "sourceSub": "seus registros", - "forwarder": "Collector", - "forwarderSub": "escuta na porta {{port}}", - "utmstack": "UTMStack", - "utmstackSub": "alertas e correlação", - "flow1": "registros", - "flow2": "seguro" - }, - "noInstall": "Nada é instalado em {{source}} — você apenas redireciona seus registros para o Collector.", - "install": { - "title": "Instalar o UTMStack Collector", - "body": "O Collector é um serviço Linux que recebe registros dos seus dispositivos e os envia ao UTMStack. Um único Collector gerencia múltiplas integrações ao mesmo tempo.", - "reuse": "Já tem um Collector em execução? Pule esta etapa — aponte {{source}} para o existente usando o host e a porta abaixo." - }, - "tls": { - "title": "Opcional — Habilitar criptografia TLS", - "intro": "Por padrão o listener aceita TCP/UDP simples. Para criptografar o tráfego syslog em trânsito, carregue os certificados primeiro e depois reative o listener com o protocolo tls.", - "step1": "1 · Carregar seu certificado e chave (uma vez por Collector)", - "step1Note": "Um certificado CA opcional pode ser adicionado como terceiro argumento. Se omitido, o certificado folha é usado como CA.", - "step2": "2 · Reativar o listener com TLS" - }, - "httpsCerts": { - "title": "Carregue o certificado TLS no Collector", - "body": "Esta integração usa um listener HTTPS na porta {{port}}, então o Collector precisa de um certificado e uma chave carregados antes de habilitá-la:" - }, - "uninstall": { - "title": "Opcional — Desinstalar o Collector", - "body": "Execute este comando no host onde o Collector está instalado para parar o serviço e remover todos os seus arquivos." - }, - "instanceHeader": { - "title": "Cabeçalho de autorização", - "body": "Inclua este cabeçalho Authorization em cada requisição enviada à instância. O segredo da chave de API é revelado apenas uma vez ao gerá-la — copie-o naquele momento e cole no lugar do marcador abaixo.", - "tabSimple": "Simples", - "tabBatch": "Lote" - }, - "manualCommand": { - "title": "Optional — Enable via the command line instead", - "intro": "Prefer the terminal? SSH into the Collector host and run the command below — it matches whatever protocol and port you have selected above.", - "certStep": "1 · Load your certificate and key (once per Collector)", - "enableStep": "2 · Enable the integration" - } - }, - "cisco": { - "source": "Cisco ASA", - "step1": { - "title": "Ativar o listener Cisco ASA no Collector", - "body": "No host onde o Collector está instalado, execute este comando para abrir o listener de registros Cisco ASA:", - "note": "Para usar TCP em vez de UDP, substitua udp por tcp no comando acima." - }, - "step2": { - "title": "Configurar o Cisco ASA para encaminhar registros", - "body": "No seu Cisco ASA, habilite o syslog e aponte-o para o host do Collector na porta {{port}}. Execute estes comandos no modo EXEC privilegiado (substitua pelo nome da sua interface interna ou de gerenciamento):" - } - }, - "ciscoSwitch": { - "source": "Cisco Switch", - "step1": { - "title": "Ativar o listener Cisco Switch no Collector", - "body": "No host onde o Collector está instalado, execute este comando para abrir o listener de registros Cisco Switch:", - "note": "Para usar TCP em vez de UDP, substitua udp por tcp no comando acima." - }, - "step2": { - "title": "Configurar o switch para encaminhar registros", - "body": "No modo EXEC privilegiado do seu Cisco switch, habilite o syslog e aponte-o para o host do Collector na porta {{port}}:" - } - }, - "ciscoMeraki": { - "source": "Cisco Meraki", - "step1": { - "title": "Ativar o listener Cisco Meraki no Collector", - "body": "No host onde o Collector está instalado, execute este comando para abrir o listener de registros Cisco Meraki:", - "note": "Para usar TCP em vez de UDP, substitua udp por tcp no comando acima." - }, - "step2": { - "title": "Configurar o Meraki para encaminhar registros", - "body": "No Meraki Dashboard, vá para Network-wide → Configure → General, role até a seção Reporting e adicione um servidor syslog com o IP do Collector e a porta {{port}}. Selecione todos os papéis que deseja encaminhar." - } - }, - "ciscoFirepower": { - "source": "Cisco Firepower", - "step1": { - "title": "Ativar o listener Cisco Firepower no Collector", - "body": "No host onde o Collector está instalado, execute este comando para abrir o listener de registros Cisco Firepower:", - "note": "Para usar TCP em vez de UDP, substitua udp por tcp no comando acima." - }, - "step2": { - "title": "Configurar o Firepower para encaminhar registros", - "body": "No Firepower Management Center (FMC), vá para Devices → Platform Settings, edite ou crie uma política e navegue até Syslog → Syslog Servers. Adicione o IP do Collector com a porta {{port}} (UDP), atribua a política aos seus dispositivos e implante." - } - }, - "office365": { - "intro": { - "title": "Como funciona", - "body": "O UTMStack conecta-se ao Microsoft 365 usando um app registrado no Azure AD e consulta a API de Atividade de Gerenciamento do Office 365 para obter eventos de auditoria e segurança. Nenhum agente é instalado no seu tenant.", - "diagram": { - "source": "eventos de auditoria e segurança", - "edge": "Management API", - "utmstackSub": "correlação e alertas" - }, - "note": "O UTMStack requer apenas permissões de leitura — nenhuma permissão de escrita é solicitada." - }, - "appSection": "Registro de Aplicativo no Azure", - "steps": { - "azurePortal": { - "title": "Abrir o Microsoft Entra ID", - "body": "Abra o Portal do Azure (portal.azure.com) e clique em Microsoft Entra ID." - }, - "appRegistrations": { - "title": "Ir para Registros de aplicativos", - "body": "No menu esquerdo, clique em Registros de aplicativos." - }, - "registerApp": { - "title": "Registrar um novo aplicativo", - "body": "Clique em Novo registro. Nomeie como UTMStack O365 Agent, selecione Somente contas neste diretório organizacional (Locatário único) e clique em Registrar." - }, - "clientSecret": { - "title": "Criar um segredo do cliente", - "body": "Vá para Certificados e segredos → Novo segredo do cliente. Adicione uma descrição, defina a expiração para 730 dias (24 meses) e clique em Adicionar.", - "copyNote": "Copie o Valor do segredo imediatamente — ele é exibido apenas uma vez e não pode ser recuperado depois." - }, - "apiPermissions": { - "title": "Adicionar permissões da Office 365 Management API", - "body": "Vá para Permissões de API → Adicionar uma permissão e pesquise por Office 365 Management APIs." - }, - "activityFeed": { - "title": "Conceder permissões de ActivityFeed", - "body": "Selecione Permissões de aplicativo e adicione ActivityFeed.Read e ActivityFeed.ReadDlp. Clique em Conceder consentimento de administrador e confirme." - }, - "graphPermissions": { - "title": "Adicionar permissões do Microsoft Graph", - "body": "De volta em Adicionar uma permissão, clique em Microsoft Graph." - }, - "delegatedPermissions": { - "title": "Adicionar permissões delegadas de SecurityAlert", - "body": "Selecione Permissões delegadas e adicione SecurityAlert.Read.All e SecurityAlert.ReadWrite.All. Clique em Conceder consentimento de administrador e confirme." - }, - "appPermissions": { - "title": "Adicionar permissões de aplicativo de SecurityAlert", - "body": "Selecione Permissões de aplicativo e adicione SecurityAlert.Read.All e SecurityAlert.ReadWrite.All. Clique em Conceder consentimento de administrador e confirme." - }, - "noteIds": { - "title": "Copiar os IDs do aplicativo", - "body": "Vá para a Visão geral do app e copie o ID do aplicativo (cliente) e o ID do diretório (locatário). Você também precisará do valor do segredo copiado na etapa 4." - } - }, - "credentialsSection": "Credenciais", - "credentials": { - "title": "Conectar seu tenant do Microsoft 365", - "body": "Insira os dados das etapas acima. O UTMStack verifica as credenciais antes de salvá-las. Você pode adicionar múltiplos grupos de configuração." - }, - "fields": { - "tenantId": { - "label": "Tenant ID (ID de diretório)" - }, - "clientId": { - "label": "Client ID (ID de aplicativo)" - }, - "clientSecret": { - "label": "Segredo do cliente" - }, - "cloudEnv": { - "label": "Ambiente de nuvem (opcional)", - "hint": "Commercial (padrão), GCC, GCCHigh ou DoD" - } - } - }, - "github": { - "source": "GitHub", - "step1": { - "title": "Ativar o listener de webhook do GitHub no Collector", - "body": "No host onde o Collector está instalado, execute este comando para abrir o listener HTTPS de webhook para o GitHub:", - "tokenNote": "O terminal exibirá um token secreto — copie-o imediatamente. Ele não será exibido novamente." - }, - "certWarning": { - "title": "GitHub requer um certificado TLS assinado por uma CA", - "body": "O GitHub só entrega webhooks para endpoints HTTPS com um certificado emitido por uma CA pública (certificados auto-assinados são rejeitados). Certifique-se de que o host do Collector tenha um certificado de domínio válido antes de registrar o webhook." - }, - "step2": { - "title": "Registrar o webhook no GitHub", - "body": "No seu repositório ou organização, vá para Settings → Webhooks → Add webhook e preencha o formulário:", - "payloadUrl": "Payload URL", - "contentType": "Content type", - "secret": "Secret", - "secretHint": "Cole o token impresso pelo Collector na etapa anterior.", - "events": "Which events", - "eventsHint": "Send me everything — ou selecione tipos de eventos específicos." - } - }, - "aix": { - "source": "Servidor AIX", - "step1": { - "title": "Ativar o listener AIX no Collector", - "body": "No host onde o Collector está instalado, execute este comando para abrir o listener de registros AIX:", - "note": "Para usar TCP em vez de UDP, substitua udp por tcp no comando acima." - }, - "step2": { - "title": "Configurar o AIX para encaminhar registros", - "body": "No seu sistema AIX, configure o serviço syslog para redirecionar seus registros ao host do Collector na porta {{port}}. Consulte a documentação da IBM para a sintaxe exata — ela varia entre versões do AIX." - } - }, - "as400": { - "intro": { - "title": "Como funciona", - "body": "O Coletor AS/400 é um serviço Linux que se conecta diretamente aos seus sistemas AS/400 (IBM i) e extrai entradas do diário de segurança, transmitindo-as com segurança ao UTMStack para correlação e alertas.", - "note": "Nada é instalado no AS/400 — o Coletor é executado em um host Linux que tenha acesso de rede aos seus sistemas AS/400.", - "diagram": { - "source": "seus diários", - "edge1": "diários", - "collector": "Coletor AS/400", - "collectorSub": "extrai do AS/400", - "edge2": "seguro", - "utmstackSub": "alertas e correlação" - } - }, - "install": { - "title": "Instalar o Coletor AS/400", - "body": "Execute este comando em um host Linux que possa alcançar tanto o UTMStack quanto seus sistemas AS/400 pela rede.", - "reuse": "Já tem o Coletor AS/400 instalado? Pule esta etapa — apenas adicione seus servidores ao arquivo de configuração na próxima etapa." - }, - "configure": { - "title": "Adicionar seus servidores AS/400", - "body": "Edite o as400-config.yaml no diretório de instalação do coletor e adicione cada sistema AS/400 que deseja monitorar:", - "note": "Você pode listar múltiplos servidores. O coletor monitora este arquivo e recarrega automaticamente ao salvar — sem necessidade de reinicialização." - }, - "journal": { - "title": "Ativar o diário de auditoria no AS/400", - "body": "Em cada sistema AS/400, certifique-se de que o diário de auditoria de segurança QAUDJRN esteja ativo. Consulte a documentação da IBM para as etapas exatas — o procedimento varia entre versões do IBM i." - }, - "uninstall": { - "title": "Opcional — Desinstalar o Coletor", - "body": "Execute este comando no host onde o Coletor AS/400 está instalado para parar o serviço e remover todos os arquivos." - } - }, - "bitdefender": { - "intro": { - "title": "Como funciona", - "body": "UTMStack conecta-se ao Bitdefender GravityZone usando sua chave de API para configurar o Event Push Service. O GravityZone então envia eventos de segurança diretamente ao UTMStack para correlação e alertas.", - "diagram": { - "source": "eventos de endpoints", - "edge": "Event Push Service", - "utmstackSub": "alertas e correlação" - }, - "note": "Nenhum agente é instalado no GravityZone — UTMStack registra-se como destino de push usando credenciais de API somente leitura." - }, - "whitelist": { - "title": "Adicionar IPs da Bitdefender à whitelist", - "body": "Os seguintes endereços IP do Bitdefender GravityZone devem ser permitidos no seu firewall na porta 8000 para que o Event Push Service possa alcançar o UTMStack:", - "note": "Adicione esses IPs ao seu firewall ou grupo de segurança antes de concluir a configuração." - }, - "apiSection": "Obter credenciais de API", - "api": { - "myAccount": { - "title": "Abrir Minha Conta", - "body": "No console do Bitdefender GravityZone, clique em My Account." - }, - "accessUrl": { - "title": "Anotar a Access URL", - "body": "Role até a seção Control Center API e salve a Access URL — você a inserirá no formulário de credenciais. Em seguida, abra a seção de chaves de API e clique em Add." - }, - "createKey": { - "title": "Criar uma chave de API", - "body": "Escreva uma descrição para a chave de API, selecione a opção Event Push Service API e clique em Save. Copie a chave gerada." - } - }, - "companySection": "Obter IDs de empresa", - "company": { - "myCompany": { - "title": "Abrir Minha Empresa", - "body": "No console do GravityZone, clique em My Company." - }, - "licensing": { - "title": "Anotar os IDs de empresa", - "body": "Abra a seção Licensing e salve os Company IDs que deseja monitorar — insira-os separados por vírgula no formulário de credenciais." - } - }, - "credentials": { - "title": "Inserir credenciais", - "body": "Preencha a Access URL, a chave de API, o IP público do UTMStack (onde o GravityZone enviará os eventos) e os IDs de empresa a monitorar. UTMStack verifica as credenciais antes de salvar." - }, - "fields": { - "accessUrl": { - "label": "Access URL do GravityZone" - }, - "connectionKey": { - "label": "Chave de API" - }, - "utmPublicIP": { - "label": "IP público do UTMStack" - }, - "companyIds": { - "label": "IDs de empresa (separados por vírgula)" - } - } - }, - "netflow": { - "source": "Dispositivo de rede", - "step1": { - "title": "Ativar o listener de NetFlow no Collector", - "body": "No host onde o Collector está instalado, execute este comando para abrir o coletor NetFlow na porta 2055:", - "note": "NetFlow usa apenas UDP — TCP e TLS não são suportados para este protocolo." - }, - "step2": { - "title": "Configurar o dispositivo para exportar NetFlow", - "body": "Aponte a exportação de NetFlow no seu roteador ou firewall para o host do Collector na porta {{port}} UDP. O exemplo abaixo é para Cisco IOS — consulte a documentação do seu fabricante para outras plataformas:", - "note": "Substitua pelo nome da interface onde o tráfego deve ser monitorado (ex: GigabitEthernet0/0). Aplique ingress/egress em cada interface relevante." - } - }, - "sophos": { - "intro": { - "title": "Sophos Central — Plugin de API", - "body": "O Sophos Central fornece APIs seguras para recuperar dados de eventos e alertas. O UTMStack conecta-se a essas APIs para centralizar o monitoramento e aprimorar a visibilidade de segurança — sem agente ou collector.", - "diagram": { - "source": "API do Sophos Central", - "edge": "HTTPS API", - "utmstackSub": "Ingere e correlaciona" - }, - "note": "O UTMStack consulta a API do Sophos Central periodicamente. Certifique-se de que as credenciais criadas tenham acesso de leitura a eventos e alertas." - }, - "apiSection": "Gerar credenciais de API no Sophos Central", - "steps": { - "apiCredentials": { - "title": "Abrir o gerenciamento de credenciais de API", - "body": "No Sophos Central Admin, navegue até Global Settings → API Credentials Management." - }, - "addCredential": { - "title": "Criar uma nova credencial", - "body": "Clique em Add Credential. Forneça um Nome e uma Descrição, selecione o Papel apropriado e clique em Add." - }, - "copyIds": { - "title": "Copiar Client ID e Client Secret", - "body": "Copie o Client ID e o Client Secret e armazene-os com segurança.", - "secretNote": "O Client Secret é exibido apenas uma vez. Salve-o antes de fechar esta janela." - } - }, - "credentialsSection": "Conectar ao UTMStack", - "credentials": { - "title": "Adicionar credenciais do Sophos Central", - "body": "Insira as credenciais que você acabou de criar. Você pode adicionar mais de uma conta Sophos clicando em Adicionar grupo de configuração." - }, - "fields": { - "clientId": { - "label": "Client ID" - }, - "apiKey": { - "label": "Client Secret / API Key" - } - } - }, - "mikrotik": { - "source": "Roteador MikroTik", - "step1": { - "title": "Ativar o listener do MikroTik no Collector", - "body": "No host onde o Collector está instalado, execute este comando para abrir o listener syslog do MikroTik:", - "note": "Para usar TCP em vez de UDP, substitua udp por tcp no comando acima." - }, - "step2": { - "title": "Configurar o MikroTik para encaminhar registros", - "body": "No roteador MikroTik, crie uma ação de logging remota apontando para o host do Collector na porta {{port}} e atribua-a aos tópicos relevantes. Execute o seguinte na CLI do RouterOS (Terminal no Winbox):", - "note": "Você também pode configurar pelo Winbox: System → Logging → aba Actions (adicione uma ação Remote) → depois aba Rules (adicione regras apontando para a nova ação)." - } - }, - "oracle": { - "source": "Servidor Oracle DB", - "step1": { - "title": "Ativar a integração Oracle no Collector", - "body": "No servidor onde o Collector está instalado, execute o seguinte comando para começar a receber logs do Oracle:", - "note": "O Collector começará a receber eventos syslog do Oracle na porta 7021." - }, - "step2": { - "title": "Configurar rsyslog no servidor Oracle", - "body": "Crie o arquivo de configuração do rsyslog:", - "editBody": "Abra o arquivo com seu editor preferido e adicione a seguinte configuração. Substitua BASEDIR pelo caminho de instalação do Oracle (ex.: /u01/app/oracle) e pelo endereço IP ou nome do host do Collector:", - "note": "Use @@:7021 em vez de @ se preferir entrega via TCP." - }, - "step3": { - "title": "Reiniciar o rsyslog", - "body": "Aplique a nova configuração reiniciando o serviço rsyslog:" - }, - "step4": { - "title": "Validar a configuração", - "body": "Envie mensagens de teste para verificar que o UTMStack está recebendo eventos das três fontes de logs do Oracle:", - "note": "Abra o Log Explorer e pesquise pelo texto da mensagem de teste acima para confirmar que chegaram." - } - }, - "utmstack": { - "intro": { - "title": "Como funciona", - "body": "Esta integração automonitora sua implantação do UTMStack. Um coletor leve instalado no host do UTMStack lê os logs dos próprios contêineres Docker da plataforma e os envia de volta ao UTMStack para correlação e alertas.", - "diagram": { - "source": "Logs do Docker", - "sourceSub": "Contêineres do UTMStack", - "edge1": "lê", - "collector": "Coletor", - "collectorSub": "no host", - "edge2": "ingestão", - "utmstackSub": "Correlaciona e alerta" - } - }, - "requirements": { - "title": "Executa apenas no host do UTMStack", - "body": "Esta integração só pode ser instalada em uma instância do UTMStack que execute Ubuntu ou uma distribuição da família Red Hat. Instale o coletor diretamente no servidor do UTMStack." - }, - "install": { - "title": "Instalar o coletor", - "body": "No host do UTMStack, escolha seu sistema operacional e execute o comando abaixo para baixar e instalar o coletor de automonitoramento:", - "sensitiveWarning": "Este comando contém um token de conexão sensível. Trate-o como uma senha e não o compartilhe." - }, - "after": { - "title": "O que você verá após instalar", - "item1": "O coletor se registra e aparece em Fontes de dados.", - "item2": "Os logs dos contêineres do UTMStack começam a fluir em menos de um minuto.", - "item3": "Os eventos ficam pesquisáveis no Log Explorer sob o tipo de dado utmstack." - }, - "uninstall": { - "title": "Desinstalar o coletor", - "body": "Para remover o coletor de automonitoramento do host do UTMStack, execute:" - } - }, - "endpoint": { - "title": "Detalhes de conexão", - "hint": "Configure o {{name}} para encaminhar seus logs ao Collector usando o host e a porta abaixo." - }, - "syslog": { - "sections": { - "sendLogs": { - "title": "1 · Enviar logs ao UTMStack", - "body": "Configure seu dispositivo para enviar mensagens syslog via UDP (514) ou TCP (514) ao agente UTMStack." - }, - "enableCollector": { - "title": "2 · Ativar o coletor syslog", - "body": "Ative o coletor de logs e a integração syslog no arquivo de configuração onde o agente UTMStack está instalado." - }, - "activate": { - "title": "3 · Ativar", - "body": "Ative o módulo UTMStack para que os eventos comecem a fluir para o Log Explorer." - } - } - }, - "vmware": { - "source": "VMware ESXi", - "step1": { - "title": "Ativar o listener VMware no Collector", - "body": "No host onde o Collector está instalado, execute este comando para abrir o listener syslog do VMware ESXi. O ESXi transmite via TCP:", - "note": "Para um canal criptografado, use tls em vez de tcp (carregue os certificados no Collector primeiro)." - }, - "step2": { - "title": "Apontar o syslog do ESXi para o Collector", - "body": "Abra uma sessão SSH/ESXi Shell no host (ou use o vSphere Client: Host → Configure → Advanced System Settings → Syslog.global.logHost). Defina o loghost remoto como {{host}}:{{port}} e recarregue a configuração:", - "note": "No vSphere, você pode definir Syslog.global.logHost com o mesmo valor tcp://host:port em vez de executar esxcli." - }, - "step3": { - "title": "Abrir o firewall do ESXi para syslog", - "body": "Permita o tráfego syslog de saída pelo firewall do ESXi para que o host alcance o Collector:" - } - }, - "eset": { - "source": "ESET Protect", - "step1": { - "title": "Ativar o listener ESET no Collector", - "body": "No host onde o Collector está instalado, execute este comando para abrir o listener syslog do ESET:", - "note": "Para usar TCP em vez de UDP, substitua udp por tcp no comando acima." - }, - "console": { - "moreMenu": { - "title": "Abrir o menu More", - "body": "Na barra lateral do console ESET Protect, clique no menu More." - }, - "serverConfig": { - "title": "Abrir as configurações do servidor", - "body": "Em More, abra a seção Server settings (Server configuration)." - }, - "advanced": { - "title": "Expandir as configurações avançadas", - "body": "Clique em Advanced settings para expandir a lista completa de opções de configuração." - }, - "syslog": { - "title": "Configurar o servidor Syslog", - "body": "Role até Syslog server, ative Export logs to Syslog e defina o destino como o host do Collector na porta {{port}} (UDP). O ESET envia LEEF/syslog, que o Collector ingere como o tipo de dado antivirus-esmc-eset." - } - } - }, - "kaspersky": { - "source": "Kaspersky Security", - "step1": { - "title": "Ativar o listener Kaspersky no Collector", - "body": "No host onde o Collector está instalado, execute este comando para abrir o listener syslog do Kaspersky:", - "note": "Para usar TCP em vez de UDP, substitua udp por tcp no comando acima." - }, - "console": { - "consoleSettings": { - "title": "Abrir Console settings → Integration", - "body": "Na barra lateral do Kaspersky Security Center, abra Console settings e clique no submenu Integration." - }, - "siem": { - "title": "Abrir as configurações de integração SIEM", - "body": "Em Integration, selecione SIEM e clique no link Settings para abrir a configuração de exportação." - }, - "configure": { - "title": "Configurar a exportação SIEM", - "body": "Ative a exportação e configure o Kaspersky para enviar eventos no formato Splunk (CEF) ao host do Collector na porta {{port}} (UDP). O Collector os ingere como o tipo de dado antivirus-kaspersky." - } - } + "alerts": { + "title": "Alertas", + "matching": "{{count}} correspondentes", + "subtitle": "Priorize o que importa.", + "openNow": "abertos agora.", + "view": { + "alerts": "Alertas", + "overview": "Visão geral" }, - "webroot": { - "sections": { - "login": { - "title": "1 · Acessar o console de gerenciamento", - "body": "Acesse o console de gerenciamento do Webroot. Ele abre na aba Sites." - }, - "openSettings": { - "title": "2 · Abrir Configurações", - "body": "Clique na aba Settings." - }, - "apiAccess": { - "title": "3 · Abrir API Access", - "body": "Na aba Subscriptions, clique na aba API Access." - }, - "createCredential": { - "title": "4 · Criar uma credencial de cliente", - "body": "Clique em New e preencha o Name e a Description. Leia o acordo SecureAnywhere Business Solution and Unity API e clique em Create." - }, - "noteClientSecret": { - "title": "5 · Copiar o ID e o segredo do cliente", - "body": "Salve o Client ID da lista e o Client Secret exibido apenas uma vez. Clique em \"I have made note of the client secret\" para confirmar." - }, - "fillForm": { - "title": "6 · Preencher o formulário", - "body": "Forneça o client ID e o client secret ao UTMStack. Você pode adicionar mais de um grupo de configuração do Webroot se necessário." - }, - "activate": { - "title": "7 · Ativar", - "body": "Ative o módulo UTMStack para que os eventos do Webroot comecem a fluir." - } - } - }, - "sentinelOne": { - "source": "SentinelOne", - "step1": { - "title": "Ativar o listener SentinelOne no Collector", - "body": "No host onde o Collector está instalado, execute este comando para abrir o listener syslog do SentinelOne. O SentinelOne transmite CEF via TCP:", - "note": "Para um canal criptografado, use tls em vez de tcp (carregue os certificados no Collector primeiro)." - }, - "console": { - "settings": { - "title": "Abrir as Configurações do SentinelOne", - "body": "Na barra lateral do console de gerenciamento do SentinelOne, clique no menu Settings." - }, - "syslog": { - "title": "Configurar a integração Syslog", - "body": "Vá para Integrations → Syslog e ative. Defina o host como {{host}} e a porta como {{port}}, mantenha o formato como CEF, clique em Test para verificar a conexão e depois em Save." - } - } + "toolbar": { + "searchPlaceholder": "Buscar por nome do alerta…", + "allSeverities": "Todas as severidades", + "export": "Exportar CSV", + "refresh": "Atualizar" }, - "salesforce": { - "sections": { - "openSetup": { - "title": "1 · Abrir Configuração", - "body": "Vá para Setup e selecione \"Setup for the current app\" no canto superior direito da tela." - }, - "appManager": { - "title": "2 · Abrir o App Manager", - "body": "Digite \"App Manager\" na caixa de busca rápida e selecione App Manager." - }, - "newConnectedApp": { - "title": "3 · Criar um novo Connected App", - "body": "Na tela do Lightning Experience App Manager, clique em \"New Connected App\" e preencha os campos." - }, - "oauthSettings": { - "title": "4 · Ativar as Configurações OAuth", - "body": "Na seção \"API (Enable OAuth Settings)\", marque \"Enable OAuth Settings\" e use https://login.salesforce.com/services/oauth2/success como Callback URL." - }, - "oauthScopes": { - "title": "5 · Adicionar escopos OAuth", - "body": "Selecione \"Access Connect REST API resources (chatter_api)\" em Selected OAuth Scopes." - }, - "save": { - "title": "6 · Salvar", - "body": "Salve suas alterações e selecione Continue na próxima tela." - }, - "manageConsumer": { - "title": "7 · Abrir Manage Consumer Details", - "body": "Dentro do seu Connected App, vá para \"API (Enable OAuth Settings)\" e clique em \"Manage Consumer Details\" ao lado de Consumer Key and Secret." - }, - "copyCredentials": { - "title": "8 · Copiar a chave e o segredo do consumidor", - "body": "Verifique sua identidade. O Consumer Key e o Consumer Secret aparecem em \"Consumer Details\". Copie ambos com o botão Copy." - }, - "fillForm": { - "title": "9 · Preencher o formulário", - "body": "Forneça o Consumer Key, Consumer Secret, nome de usuário e senha do Salesforce ao UTMStack." - }, - "activate": { - "title": "10 · Ativar", - "body": "Ative o módulo UTMStack para que os eventos do Salesforce comecem a fluir." - } - } + "severity": { + "high": "Alta", + "medium": "Média", + "low": "Baixa" }, - "iis": { - "sections": { - "enableModule": { - "title": "1 · Ativar o módulo IIS do Filebeat", - "body": "No host do agente UTMStack, execute:\ncd \"C:\\Program Files\\UTMStack\\UTMStack Agent\\beats\\filebeat\\\" && filebeat modules enable iis" - }, - "configureModule": { - "title": "2 · Configurar o módulo IIS", - "body": "Edite C:\\Program Files\\UTMStack\\UTMStack Agent\\beats\\filebeat\\modules.d\\iis.yml conforme mostrado abaixo para apontar os diretórios de logs IIS que deseja enviar." - }, - "activate": { - "title": "3 · Ativar", - "body": "Ative o módulo UTMStack para que os eventos IIS comecem a fluir." - } - } + "status": { + "open": "Aberto", + "in_review": "Em revisão", + "completed": "Concluído", + "auto": "Revisão automática" }, - "filebeat": { - "sections": { - "installRsyslog": { - "title": "1 · Instalar rsyslog", - "body": "Certifique-se de que o rsyslog está instalado no host. Use o gerenciador de pacotes da sua distribuição (apt, dnf, yum)." - }, - "configureRsyslog": { - "title": "2 · Configurar o rsyslog para encaminhar ao UTMStack", - "body": "Edite /etc/rsyslog.conf (ou um arquivo em /etc/rsyslog.d/) e adicione uma regra de encaminhamento que direcione para o agente UTMStack via UDP ou TCP na porta 514." - }, - "restartRsyslog": { - "title": "3 · Reiniciar o rsyslog", - "body": "Reinicie o serviço rsyslog: sudo systemctl restart rsyslog" - }, - "enableCollector": { - "title": "4 · Ativar o coletor de logs do Linux", - "body": "Ative o coletor de logs e a integração de Linux Logs no arquivo de configuração onde o agente UTMStack está instalado." - } - } + "statusTabs": { + "all": "Todos" }, - "json": { - "sections": { - "overview": { - "title": "1 · Usar o endpoint de ingestão HTTP/JSON", - "body": "O UTMStack aceita eventos JSON arbitrários via HTTPS. Envie uma requisição POST com uma lista de eventos; o UTMStack os processa e roteia pelo parser configurado." - }, - "auth": { - "title": "2 · Autenticar com um token de federação", - "body": "Obtenha um token de federação em Configurações → Connection Key e envie-o como Bearer token no cabeçalho Authorization." - } - }, - "endpoint": { - "title": "Endpoint de ingestão JSON", - "hint": "Use este formato de requisição na sua aplicação ou em um cron job. O token é a chave de federação em Configurações → Connection Key." - } - }, - "ldap": { - "sections": { - "openServerManager": { - "title": "1 · Abrir o Server Manager", - "body": "No controlador de domínio AD, abra o Server Manager." - }, - "addRoles": { - "title": "2 · Adicionar Funções e Recursos", - "body": "Escolha \"Adicionar funções e recursos\" no menu Gerenciar." - }, - "selectCertServices": { - "title": "3 · Selecionar Active Directory Certificate Services", - "body": "Na etapa de Funções do Servidor, selecione Active Directory Certificate Services." - }, - "installServices": { - "title": "4 · Instalar o serviço de função da Autoridade de Certificação", - "body": "Na etapa de Serviços de Função, selecione Autoridade de Certificação e conclua o assistente." - }, - "configureAdCs": { - "title": "5 · Configurar o AD CS", - "body": "Após a instalação, clique na notificação para configurar o AD CS e escolha Autoridade de Certificação como o serviço de função a configurar." - }, - "pickCaType": { - "title": "6 · Escolher o tipo de CA", - "body": "Escolha Enterprise CA → Root CA → Criar uma nova chave privada." - }, - "setValidity": { - "title": "7 · Definir o período de validade do certificado", - "body": "Defina um período de validade adequado para sua organização (5 anos é o habitual)." - }, - "confirm": { - "title": "8 · Confirmar e instalar", - "body": "Revise as configurações e clique em Configurar para concluir." - }, - "restart": { - "title": "9 · Reiniciar o controlador de domínio", - "body": "Reinicie o controlador de domínio para que LDAPS fique disponível na porta TCP 636." - }, - "activate": { - "title": "10 · Ativar", - "body": "Ative o módulo UTMStack para que os eventos de auditoria do AD comecem a fluir." - } - } + "overview": { + "overTime": "Alertas ao longo do tempo", + "matchingAlerts": "alertas correspondentes", + "noData": "Sem dados.", + "bySeverity": "Por severidade", + "byStatus": "Por estado" }, - "vulnerabilities": { - "sections": { - "overview": { - "title": "1 · Sobre o scanner de vulnerabilidades", - "body": "O módulo de vulnerabilidades do UTMStack escaneia os ativos descobertos pelo módulo de Gerenciamento de Ativos e compara a impressão digital deles com o banco de dados CVE." - }, - "scope": { - "title": "2 · Definir o escopo da varredura", - "body": "Use o módulo de Gerenciamento de Ativos para registrar os hosts que deseja escanear. O scanner de vulnerabilidades será executado periodicamente contra eles." - }, - "activate": { - "title": "3 · Ativar", - "body": "Ative o módulo UTMStack para iniciar a varredura." - } - } + "filters": { + "add": "Adicionar filtro", + "clearAll": "Limpar tudo", + "filterValues": "Filtrar valores…", + "loadingValues": "Carregando valores…", + "noValues": "Nenhum valor encontrado.", + "pickValue": "Escolha um valor para adicionar o filtro.", + "empty": "(vazio)", + "cancel": "Cancelar", + "addBtn": "Adicionar" }, - "assetScanner": { - "sections": { - "overview": { - "title": "1 · Sobre o Gerenciamento de Ativos", - "body": "O módulo de Gerenciamento de Ativos descobre e inventaria hosts, softwares e serviços em toda a sua rede." - }, - "agentRequirement": { - "title": "2 · Requisito do agente", - "body": "A descoberta de ativos usa agentes UTMStack em execução em hosts Linux, Windows ou macOS. Instale o agente nos sistemas que deseja inventariar." - }, - "activate": { - "title": "3 · Ativar", - "body": "Ative o módulo UTMStack para iniciar a descoberta de ativos." - } - } + "ops": { + "CONTAIN": "contém", + "IS": "é", + "IS_NOT": "não é", + "EXIST": "existe", + "DOES_NOT_EXIST": "não existe" }, - "fileIntegrity": { - "sections": { - "enableAuditPolicy": { - "title": "1 · Ativar a Auditoria de Acesso a Objetos", - "body": "No host Windows, abra Política de Grupo → Configuração do Computador → Configurações do Windows → Configurações de Segurança → Configuração de Política de Auditoria Avançada → Acesso a Objetos e ative \"Auditar Sistema de Arquivos\"." - }, - "configureFolderAuditing": { - "title": "2 · Configurar auditoria de pastas", - "body": "Em cada pasta que deseja monitorar, abra Propriedades → Segurança → Avançado → Auditoria e adicione uma entrada de auditoria para os responsáveis e tipos de acesso desejados." - }, - "verifyEvents": { - "title": "3 · Verificar se os eventos aparecem no log de Segurança", - "body": "Abra o Visualizador de Eventos e confirme que os eventos 4663/4670 estão sendo gerados quando os objetos auditados são acessados." - }, - "activate": { - "title": "4 · Ativar", - "body": "Ative o módulo UTMStack para que os eventos de integridade de arquivos comecem a fluir." - } - } + "fields": { + "adversary_domain": "Domínio do adversário", + "adversary_geolocation_asn": "ASN do adversário", + "adversary_geolocation_aso": "ASO do adversário", + "adversary_geolocation_country": "País do adversário", + "adversary_host": "Host do adversário", + "adversary_ip": "IP do adversário", + "adversary_url": "URL do adversário", + "adversary_user": "Utilizador do adversário", + "assignee": "Atribuído a", + "category": "Categoria", + "dataSource": "Sensor", + "dataType": "Tipo de dado", + "description": "Descrição", + "id": "ID", + "impactScore": "Risco", + "impact_availability": "Disponibilidade", + "impact_confidentiality": "Confidencialidade", + "impact_integrity": "Integridade", + "incidentDetail_incidentName": "Nome do incidente", + "incidentDetail_incidentId": "Id do incidente", + "isIncident": "É incidente", + "name": "Nome do alerta", + "notes": "Notas", + "severity": "Severidade", + "status": "Estado", + "tags": "Etiquetas", + "target_domain": "Domínio do alvo", + "target_geolocation_asn": "ASN do alvo", + "target_geolocation_aso": "ASO do alvo", + "target_geolocation_country": "País do alvo", + "target_host": "Host do alvo", + "target_ip": "IP do alvo", + "target_url": "URL do alvo", + "target_user": "Utilizador do alvo", + "technique": "Técnica" }, - "socAi": { - "sections": { - "overview": { - "title": "1 · Sobre o SOC AI", - "body": "O SOC AI aprimora o UTMStack com um analista baseado em LLM que resume alertas e sugere próximos passos. Ele opera com o provedor que você configurar." - }, - "chooseProvider": { - "title": "2 · Escolher um provedor", - "body": "Escolha um provedor — OpenAI, Anthropic, Azure OpenAI, Google Gemini, Ollama, Mistral, DeepSeek, Groq ou um endpoint personalizado compatível com OpenAI." - }, - "configureCredentials": { - "title": "3 · Configurar credenciais", - "body": "Forneça a chave de API e (quando aplicável) o nome do modelo e a URL do endpoint." - }, - "activate": { - "title": "4 · Ativar", - "body": "Ative o módulo UTMStack para que o SOC AI comece a analisar os alertas." - } - } + "tagFilter": { + "tags": "Etiquetas", + "tag_one": "{{count}} etiqueta", + "tag_other": "{{count}} etiquetas", + "clearSelection": "Limpar seleção", + "noTags": "Sem etiquetas" }, - "windowsFaa": { - "sections": { - "enableAuditPolicy": { - "title": "1 · Ativar a Auditoria de Acesso a Objetos", - "body": "No host Windows, abra Política de Grupo → Configuração do Computador → Configurações do Windows → Configurações de Segurança → Configuração de Política de Auditoria Avançada → Acesso a Objetos e ative \"Auditar Sistema de Arquivos\"." - }, - "configureFolderAuditing": { - "title": "2 · Configurar auditoria de pastas", - "body": "Em cada pasta que deseja monitorar, abra Propriedades → Segurança → Avançado → Auditoria e adicione uma entrada de auditoria para os responsáveis e tipos de acesso desejados." - }, - "activate": { - "title": "3 · Ativar", - "body": "Ative o módulo UTMStack para que os eventos de atividade de arquivos comecem a fluir." - } - } + "bulk": { + "selected": "{{count}} selecionados", + "setStatus": "Definir estado", + "addTag": "Adicionar etiqueta", + "noTags": "Sem etiquetas", + "addToIncident": "Adicionar a incidente", + "clear": "Limpar" }, - "awsBeanstalk": { - "sections": { - "openConsole": { - "title": "1 · Abrir o console do Elastic Beanstalk", - "body": "No console da AWS, abra o Elastic Beanstalk." - }, - "environment": { - "title": "2 · Abrir a página de gerenciamento do ambiente", - "body": "Navegue até a página de gerenciamento do ambiente que deseja monitorar." - }, - "configuration": { - "title": "3 · Abrir Configuração", - "body": "Escolha Configuração." - }, - "software": { - "title": "4 · Modificar a configuração de Software", - "body": "Na categoria de configuração de Software, escolha Modificar." - }, - "s3LogStorage": { - "title": "5 · Ativar armazenamento de logs no S3", - "body": "Em armazenamento de logs S3, escolha Rotacionar logs para enviar os logs rotacionados ao Amazon S3." - }, - "cloudwatchStreaming": { - "title": "6 · Ativar o streaming do CloudWatch Logs", - "body": "Em Streaming de logs de instância para CloudWatch Logs, ative o streaming, defina o período de retenção e escolha se deseja enviar os logs existentes." - }, - "activate": { - "title": "7 · Ativar", - "body": "Ative o módulo UTMStack para que os eventos do Beanstalk comecem a fluir." - } - } + "tagEditor": { + "tag": "Etiqueta", + "noTagsYet": "Ainda não há etiquetas", + "createTag": "Criar etiqueta", + "newTagName": "Nome da nova etiqueta…", + "createApply": "Criar e aplicar etiqueta", + "save": "Salvar", + "cancel": "Cancelar", + "edit": "Editar etiqueta", + "delete": "Excluir etiqueta", + "systemLocked": "Etiqueta do sistema (bloqueada)", + "alreadyExists": "Essa etiqueta já existe.", + "color": "Cor {{color}}", + "createRule": "Criar regra de marcação com esta etiqueta" }, - "awsFargate": { - "sections": { - "taskDefinition": { - "title": "1 · Atualizar a definição de tarefa", - "body": "Na definição de tarefa do Fargate, defina logDriver como \"awslogs\" e especifique o nome do grupo de logs." - }, - "cloudwatchLogs": { - "title": "2 · Confirmar que o CloudWatch Logs está recebendo logs", - "body": "Abra o console do CloudWatch Logs e confirme que o grupo de logs está sendo preenchido quando as tarefas são executadas." - }, - "iamPrerequisite": { - "title": "3 · Pré-requisito do usuário IAM", - "body": "Esta integração compartilha credenciais com o módulo AWS IAM User — certifique-se de que ele está configurado com CloudWatchLogsReadOnlyAccess." - }, - "activate": { - "title": "4 · Ativar", - "body": "Ative o módulo UTMStack para que os eventos do Fargate comecem a fluir." - } - } + "table": { + "actions": "Ações", + "alert": "Alerta", + "status": "Estado", + "technique": "Técnica", + "severity": "Severidade", + "risk": "Risco", + "echoes": "Ecos", + "time": "Hora", + "riskHint": "Pontuação de risco (0–100), colorida por severidade", + "source": "Origem", + "adversary": "Adversário" }, - "awsIamUser": { - "sections": { - "iamConsole": { - "title": "1 · Abrir o console IAM", - "body": "No console da AWS, acesse IAM → Users → Add users." - }, - "createUser": { - "title": "2 · Criar o usuário", - "body": "Escolha um nome de usuário (ex.: utmstack-ingest). Selecione acesso programático." - }, - "programmaticAccess": { - "title": "3 · Definir o tipo de credencial", - "body": "Selecione \"Chave de acesso — Acesso programático\"." - }, - "attachPolicy": { - "title": "4 · Anexar a política de leitura do CloudWatch", - "body": "Anexe a política gerenciada pela AWS CloudWatchLogsReadOnlyAccess." - }, - "review": { - "title": "5 · Revisar o usuário", - "body": "Revise os detalhes do usuário e clique em Criar usuário." - }, - "copyKeys": { - "title": "6 · Copiar o ID da chave de acesso e o segredo", - "body": "Copie o ID da chave de acesso e a Chave de acesso secreta — o segredo é exibido apenas uma vez." - }, - "createLogGroup": { - "title": "7 · Criar um grupo de logs do CloudWatch", - "body": "No CloudWatch → Log groups, crie um grupo de logs com o nome \"utmstack\" — outras integrações AWS serão entregues a ele." - }, - "fillForm": { - "title": "8 · Preencher o formulário", - "body": "Forneça a chave de acesso, o segredo, a região padrão e o nome do grupo de logs (ex.: \"utmstack\") ao UTMStack." - }, - "activate": { - "title": "9 · Ativar", - "body": "Ative o módulo do UTMStack para que os eventos AWS comecem a fluir." - } - } + "row": { + "createRuleFromAlert": "Criar uma tag a partir deste alerta", + "createIncident": "Criar incidente a partir deste alerta", + "viewIncident": "Ver detalhes do incidente", + "assignedTo": "Atribuído a {{user}}", + "echoesTooltip": "{{count}} ecos — clique para expandir", + "echoesEmpty": "Sem ecos registrados" }, - "awsLambda": { - "sections": { - "iamPrerequisite": { - "title": "1 · Pré-requisito de usuário IAM", - "body": "O Lambda depende do módulo de usuário AWS IAM — certifique-se de que essa integração esteja configurada primeiro com CloudWatchLogsReadOnlyAccess." - }, - "cloudwatchStream": { - "title": "2 · Lambda já transmite para o CloudWatch Logs", - "body": "O AWS Lambda publica automaticamente os logs de execução no CloudWatch Logs em /aws/lambda/. O UTMStack ingere dados do grupo de logs configurado na etapa de usuário IAM." - }, - "activate": { - "title": "3 · Ativar", - "body": "Ative o módulo do UTMStack para que os eventos do Lambda comecem a fluir." - } - } + "echoes": { + "title": "{{count}} ecos", + "close": "Fechar", + "empty": "Nenhum eco registrado para este alerta.", + "loadError": "Não foi possível carregar os ecos." }, - "awsSqlServer": { - "sections": { - "openRds": { - "title": "1 · Abrir o console do Amazon RDS", - "body": "Abra https://console.aws.amazon.com/rds/." - }, - "pickDb": { - "title": "2 · Selecionar a instância do banco de dados", - "body": "No painel de navegação, escolha Databases e selecione a instância de banco de dados que deseja monitorar." - }, - "modify": { - "title": "3 · Modificar a instância", - "body": "Escolha Modify." - }, - "logExports": { - "title": "4 · Habilitar exportação de logs", - "body": "Na seção Log exports, escolha Error log e Agent log para publicar no CloudWatch Logs." - }, - "apply": { - "title": "5 · Aplicar alterações", - "body": "Escolha Continue e, em seguida, Modify DB Instance na página de resumo." - }, - "activate": { - "title": "6 · Ativar", - "body": "Ative o módulo do UTMStack para que os eventos do SQL Server comecem a fluir." - } - } + "list": { + "loading": "Carregando alertas…", + "loadError": "Não foi possível carregar os alertas.", + "retry": "Tentar novamente", + "empty": "Nenhum alerta corresponde a esta visão." }, - "awsPostgresql": { - "sections": { - "openRds": { - "title": "1 · Abrir o console do Amazon RDS", - "body": "Abra https://console.aws.amazon.com/rds/." - }, - "pickDb": { - "title": "2 · Selecionar a instância do banco de dados", - "body": "No painel de navegação, escolha Databases e selecione a instância de banco de dados que deseja modificar." - }, - "logExports": { - "title": "3 · Habilitar exportação de logs", - "body": "Na seção Log exports, escolha o log PostgreSQL para publicar no CloudWatch Logs." - }, - "apply": { - "title": "4 · Aplicar alterações", - "body": "Escolha Continue e, em seguida, Modify DB Instance na página de resumo." - }, - "activate": { - "title": "5 · Ativar", - "body": "Ative o módulo do UTMStack para que os eventos do PostgreSQL comecem a fluir." + "badge": { + "incident": "Incidente", + "aiAssessed": "Avaliado por IA" + }, + "drawer": { + "setStatus": "Definir estado", + "completeFalsePositive": "Concluir + falso positivo", + "addToIncident": "Adicionar a incidente", + "partOfIncident": "Parte de um incidente", + "tabs": { + "summary": "Resumo", + "parties": "Partes", + "events": "Eventos", + "history": "Histórico" + }, + "section": { + "description": "Descrição", + "solution": "Solução", + "references": "Referências", + "details": "Detalhes", + "yourNotes": "Suas notas", + "notes": "Notas" + }, + "details": { + "severity": "Severidade", + "risk": "Risco", + "category": "Categoria", + "technique": "Técnica", + "sensor": "Sensor", + "dataType": "Tipo de dado", + "alertId": "ID do alerta", + "statusNote": "Nota de estado", + "assignee": "Responsável" + }, + "incidentDetail": { + "incident": "Incidente", + "id": "ID", + "createdBy": "Criado por", + "created": "Criado" + }, + "notesPlaceholder": "Adicione notas de investigação…", + "saveNotes": "Salvar notas", + "assignee": "Atribuir", + "assign": "Atribuir", + "unassign": "Remover atribuição", + "unassigned": "Sem responsável", + "loadingUsers": "Carregando usuários…", + "observationLabel": "Observação", + "observationPlaceholder": "Adicionar uma observação…", + "cancel": "Cancelar", + "continue": "Continuar" + }, + "related": { + "sample": "Uma amostra de até ~11 eventos que o mecanismo armazenou neste alerta. Use «Ver todos os registros relacionados» para o conjunto completo e sem limite.", + "loadingEchoes": "Carregando os eventos dos seus ecos…", + "sampleWithEchoes": "Os eventos guardados neste alerta e nos seus {{count}} ecos ({{read}} lidos). Use «Ver todos os registros relacionados» para o conjunto completo e sem limite.", + "empty": "Nenhum evento de amostra armazenado neste alerta. Carregue o conjunto correlacionado completo no Explorador de registros.", + "viewAll": "Ver todos os registros relacionados" + }, + "party": { + "source": "Origem / alvo", + "adversary": "Adversário", + "noData": "Sem dados.", + "ip": "IP", + "host": "Host", + "user": "Usuário", + "domain": "Domínio", + "country": "País" + }, + "history": { + "empty": "Nenhum histórico registrado.", + "by": "por {{user}}", + "actions": { + "UPDATE_STATUS": "Estado atualizado", + "UPDATE_TAGS": "Etiquetas atualizadas", + "UPDATE_NOTES": "Notas atualizadas", + "UPDATE_SOLUTION": "Solução atualizada", + "MARK_AS_INCIDENT": "Marcado como incidente" + }, + "detail": { + "statusTo": "Estado → {{status}}", + "tags": "Etiquetas: {{tags}}", + "aiAdded": "Avaliação de IA adicionada", + "observationAdded": "Observação adicionada", + "notesUpdated": "Notas atualizadas" } - } }, - "awsTrafficMirror": { - "sections": { - "createTarget": { - "title": "1 · Criar um destino de espelhamento de tráfego", - "body": "No console da VPC, crie um Traffic Mirror Target apontando para a interface de rede da VM do agente UTMStack." - }, - "createFilter": { - "title": "2 · Criar um filtro de espelhamento de tráfego", - "body": "Crie um Traffic Mirror Filter e adicione regras de entrada/saída para os protocolos que deseja espelhar (ex.: todo TCP, todo UDP)." - }, - "createSession": { - "title": "3 · Criar uma sessão de espelhamento de tráfego", - "body": "Crie uma Traffic Mirror Session que associe cada interface de rede de origem ao destino e ao filtro criados." - }, - "iamPrerequisite": { - "title": "4 · Pré-requisito de usuário IAM", - "body": "Certifique-se de que o módulo de usuário AWS IAM também esteja configurado para que o UTMStack possa ler os VPC flow logs quando necessário." - }, - "activate": { - "title": "5 · Ativar", - "body": "Ative o módulo do UTMStack para que o tráfego espelhado comece a ser analisado." + "ai": { + "title": "Avaliação de IA do SOC", + "risk": "risco {{risk}}", + "score": "{{score}}/100", + "generate": "Gerar resumo de IA", + "hint": "O SOC-AI investiga este alerta e adiciona uma avaliação.", + "generating": "Analisando o alerta… pode levar um minuto.", + "ready": "Resumo de IA pronto", + "failed": "Não foi possível gerar o resumo de IA", + "slow": "O resumo de IA está demorando mais que o esperado. Ele aparecerá no alerta quando estiver pronto." + }, + "incident": { + "titleAdd_one": "Adicionar {{count}} alerta a um incidente", + "titleAdd_other": "Adicionar {{count}} alertas a um incidente", + "new": "Novo incidente", + "existing": "Incidente existente", + "nameLabel": "Nome do incidente", + "namePlaceholder": "ex.: Suspeita de intrusão de Scattered Spider", + "descriptionLabel": "Descrição", + "descriptionPlaceholder": "Resumo opcional…", + "pickLabel": "Escolha um incidente", + "loading": "Carregando…", + "selectPlaceholder": "Selecione um incidente…", + "willLink_one": "{{count}} alerta será vinculado.", + "willLink_other": "{{count}} alertas serão vinculados.", + "cancel": "Cancelar", + "create": "Criar incidente", + "add": "Adicionar a incidente" + }, + "toast": { + "statusUpdated": "Estado atualizado", + "statusFailed": "Falha ao atualizar o estado", + "tagsUpdated": "Etiquetas atualizadas", + "tagsFailed": "Falha ao atualizar as etiquetas", + "tagCreateFailed": "Falha ao criar a etiqueta", + "tagUpdated": "Etiqueta atualizada", + "tagUpdateFailed": "Falha ao atualizar a etiqueta", + "tagDeleted": "Etiqueta excluída", + "tagDeleteFailed": "Falha ao excluir a etiqueta", + "notesSaved": "Notas salvas", + "notesFailed": "Falha ao salvar as notas", + "exportFailed": "Falha ao exportar o CSV", + "noRelatedLogs": "Nenhum registro relacionado encontrado para este alerta", + "relatedLogsFailed": "Falha ao carregar os registros relacionados", + "incidentCreated": "Incidente criado", + "alertsAdded": "Alertas adicionados ao incidente", + "incidentFailed": "Falha ao salvar o incidente", + "assigned": "Alerta atribuído", + "unassigned": "Alerta sem responsável", + "assignFailed": "Não foi possível atualizar o responsável", + "newAlertsToast_title": "Novas alertas", + "newAlertsToast_count_one": "{{count}} nova alerta", + "newAlertsToast_count_other": "{{count}} novas alertas", + "newAlertsToast_view": "Ver" + } + }, + "incidents": { + "title": "Incidentes", + "subtitle": "Agrupe, triagem e resolva alertas relacionados como incidentes.", + "refresh": "Atualizar", + "count_one": "{{count}} incidente", + "count_other": "{{count}} incidentes", + "openNow": "abertos agora", + "empty": "Nenhum incidente corresponde.", + "loadError": "Não foi possível carregar os incidentes.", + "retry": "Tentar novamente", + "unassigned": "Não atribuído", + "unknownUser": "Desconhecido", + "status": { + "open": "Aberto", + "in_review": "Em revisão", + "completed": "Concluído", + "merged": "Mesclado" + }, + "sev": { + "high": "Alta", + "medium": "Média", + "low": "Baixa", + "unknown": "Sem classificação" + }, + "toolbar": { + "search": "Buscar incidentes…", + "create": "Criar incidente", + "allSeverities": "Todas as severidades", + "export": "Exportar CSV" + }, + "statusTabs": { + "all": "Todos" + }, + "filters": { + "add": "Adicionar filtro", + "clearAll": "Limpar tudo", + "filterValues": "Filtrar valores…", + "loadingValues": "Carregando valores…", + "noValues": "Nenhum valor encontrado.", + "pickValue": "Escolha um valor para adicionar o filtro.", + "empty": "(vazio)", + "cancel": "Cancelar", + "addBtn": "Adicionar" + }, + "ops": { + "IS": "é" + }, + "layout": { + "table": "Tabela", + "board": "Quadro" + }, + "table": { + "name": "Incidente", + "status": "Status", + "severity": "Severidade", + "assignee": "Responsável", + "alerts": "Alertas", + "created": "Criado" + }, + "drawer": { + "created": "Criado {{date}}", + "alertsCount": "{{count}} alertas", + "solutionPlaceholder": "Resolução / notas de remediação…", + "solutionHint": "Salvo ao mover o incidente para Concluído.", + "tabs": { + "overview": "Resumo", + "alerts": "Alertas", + "notes": "Notas", + "history": "Histórico" + }, + "section": { + "description": "Descrição", + "solution": "Solução", + "details": "Detalhes" + }, + "details": { + "id": "ID", + "status": "Status", + "severity": "Severidade", + "assignee": "Responsável", + "created": "Criado", + "alerts": "Alertas vinculados" } - } - }, - "deceptivebytes": { - "source": "Deceptive Bytes", - "step1": { - "title": "Habilitar o listener do Deceptive Bytes no Collector", - "body": "No host onde o Collector está instalado, execute este comando para abrir o listener syslog do Deceptive Bytes:", - "note": "Para usar TCP em vez de UDP, substitua udp por tcp no comando acima." - }, - "step2": { - "title": "Configurar o Deceptive Bytes para encaminhar logs", - "body": "No console de gerenciamento do Deceptive Bytes, configure o encaminhamento syslog para enviar eventos ao host do Collector na porta {{port}} (UDP). O Deceptive Bytes emite syslog no formato CEF, que o Collector ingere como o tipo de dados deceptive-bytes." - } - }, - "fortigate": { - "source": "FortiGate firewall", - "step1": { - "title": "Habilitar o listener do FortiGate no Collector", - "body": "No host onde o Collector está instalado, execute este comando para abrir o listener syslog do FortiGate:", - "note": "Para usar TCP em vez de UDP, substitua udp por tcp no comando acima." - }, - "step2": { - "title": "Configurar o FortiGate para encaminhar logs", - "body": "No FortiGate, aponte o syslog para o host do Collector na porta {{port}}. Execute o seguinte na CLI do FortiOS (ou use Log & Report → Log Settings → Syslog na interface gráfica):", - "note": "Substitua o endereço do servidor se o Collector estiver em outro host. Para múltiplos coletores syslog, use syslogd2/syslogd3/syslogd4." - } - }, - "fortiweb": { - "source": "FortiWeb WAF", - "step1": { - "title": "Habilitar o listener do FortiWeb no Collector", - "body": "No host onde o Collector está instalado, execute este comando para abrir o listener syslog do FortiWeb:", - "note": "Para usar TCP em vez de UDP, substitua udp por tcp no comando acima." - }, - "step2": { - "title": "Configurar o FortiWeb para encaminhar logs", - "body": "No FortiWeb, crie uma política de syslog apontando para o host do Collector na porta {{port}} e habilite o registro via syslog. Execute o seguinte na CLI do FortiWeb (ou use Log & Report → Log Policy → Syslog Policy na interface gráfica):", - "note": "Certifique-se de que os tipos de log relevantes (Attack, Event, Traffic) estejam habilitados para envio via syslog nas configurações de Log & Report." - } - }, - "paloalto": { - "source": "Palo Alto firewall", - "step1": { - "title": "Habilitar o listener do Palo Alto no Collector", - "body": "No host onde o Collector está instalado, execute este comando para abrir o listener syslog do Palo Alto:", - "note": "Para usar TCP em vez de UDP, substitua udp por tcp no comando acima." - }, - "step2": { - "title": "Criar um perfil de servidor Syslog", - "body": "No PAN-OS, vá para Device → Server Profiles → Syslog e adicione um perfil. Defina o endereço do servidor como {{host}}, transporte UDP, porta {{port}} e formato BSD." - }, - "step3": { - "title": "Encaminhar logs e confirmar", - "body": "Crie um perfil de Log Forwarding (Objects → Log Forwarding) que envie os tipos de log Traffic, Threat e outros para o perfil syslog acima, vincule-o às regras de Security policy (Policies → Security → rule → Actions → Log Forwarding) e, em seguida, Commit." - } - }, - "pfsense": { - "source": "pfSense firewall", - "step1": { - "title": "Habilitar o listener do pfSense no Collector", - "body": "No host onde o Collector está instalado, execute este comando para abrir o listener syslog do pfSense:", - "note": "Para usar TCP em vez de UDP, substitua udp por tcp no comando acima." - }, - "step2": { - "title": "Habilitar registro remoto no pfSense", - "body": "Na interface web do pfSense, vá para Status → System Logs → Settings. Em Remote Logging Options, marque Enable Remote Logging, defina um servidor de log remoto como {{host}}:{{port}}, escolha quais logs enviar (ou Everything) e clique em Save." - } - }, - "sonicwall": { - "source": "SonicWall firewall", - "step1": { - "title": "Habilitar o listener do SonicWall no Collector", - "body": "No host onde o Collector está instalado, execute este comando para abrir o listener syslog do SonicWall:", - "note": "Para usar TCP em vez de UDP, substitua udp por tcp no comando acima." - }, - "step2": { - "title": "Adicionar um servidor Syslog no SonicOS", - "body": "No SonicOS, vá para Device → Log → Syslog (Manage → Log → Syslog em firmwares mais antigos) e adicione um Syslog Server com endereço {{host}} e porta {{port}}. Defina o Syslog Format como ArcSight (CEF) — o UTMStack analisa o SonicWall em CEF — e clique em Apply." - } - }, - "sophosxg": { - "source": "Sophos Firewall", - "step1": { - "title": "Habilitar o listener do Sophos Firewall no Collector", - "body": "No host onde o Collector está instalado, execute este comando para abrir o listener syslog do Sophos Firewall:", - "note": "Para usar TCP em vez de UDP, substitua udp por tcp no comando acima." - }, - "step2": { - "title": "Adicionar um servidor Syslog no Sophos Firewall", - "body": "No console do Sophos Firewall (SFOS), vá para System → System services → Log settings e adicione um Syslog Server com endereço {{host}} e porta {{port}}. Escolha os tipos de log que deseja encaminhar (firewall, IPS, ATP, web, etc.) e clique em Apply." - } - }, - "suricata": { - "source": "Suricata IDS", - "step1": { - "title": "Habilitar o listener do Suricata no Collector", - "body": "No host onde o Collector está instalado, execute este comando para abrir o listener do Suricata:", - "note": "Para usar TCP em vez de UDP, substitua udp por tcp no comando acima." - }, - "step2": { - "title": "Enviar logs EVE do Suricata para syslog", - "body": "O Suricata é ingerido como JSON (EVE). No host do Suricata, edite suricata.yaml e configure a saída eve-log para gravar no syslog:", - "note": "Em seguida, reinicie o Suricata: sudo systemctl restart suricata" - }, - "step3": { - "title": "Encaminhar syslog para o Collector", - "body": "Aponte a facilidade local5 (para onde o Suricata agora grava) para o Collector. Adicione esta regra em /etc/rsyslog.d/60-utmstack-suricata.conf no host do Suricata:", - "note": "Use @@ em vez de @ para TCP. Em seguida, reinicie o rsyslog: sudo systemctl restart rsyslog" - } - }, - "o365_graph": { - "intro": { - "title": "Como funciona", - "body": "O UTMStack se conecta ao Microsoft 365 com um app do Azure AD registrado e consulta o Microsoft Graph por eventos de segurança: alertas, incidentes, auditoria do diretório, sign-ins, detecções de risco, consultas de hunting e logs de auditoria do Purview. Nenhum agente é instalado no seu tenant.", - "diagram": { - "source": "eventos de segurança", - "edge": "Microsoft Graph", - "utmstackSub": "correlação & alertas" - }, - "note": "O UTMStack requer apenas acesso somente leitura à API do Graph — nenhuma permissão de gravação é solicitada." - }, - "appSection": "Registro de aplicativo Azure", - "steps": { - "azurePortal": { - "title": "Abrir o Microsoft Entra ID", - "body": "Abra o Portal do Azure (portal.azure.com) e clique em Microsoft Entra ID." - }, - "appRegistrations": { - "title": "Ir para Registros de aplicativo", - "body": "No menu à esquerda, clique em Registros de aplicativo." - }, - "registerApp": { - "title": "Registrar um novo aplicativo", - "body": "Clique em Novo registro. Nomeie-o UTMStack Graph Dev, selecione Somente contas neste diretório organizacional (Single-tenant) e clique em Registrar." - }, - "clientSecret": { - "title": "Criar um segredo de cliente", - "body": "Vá em Certificados e segredos → Novo segredo de cliente. Adicione uma descrição, defina a expiração como 730 dias (24 meses) e clique em Adicionar.", - "copyNote": "Copie o valor do segredo imediatamente — ele só é exibido uma vez e não poderá ser recuperado depois." - }, - "apiPermissions": { - "title": "Adicionar permissões do Microsoft Graph", - "body": "Vá em Permissões de API → Adicionar uma permissão e selecione Microsoft Graph, depois escolha Permissões de aplicativo." - }, - "graphPermissions": { - "title": "Adicionar as quatro permissões do Graph", - "body": "Adicione SecurityEvents.Read.All, Directory.Read.All, AuditLog.Read.All e IdentityRiskEvent.Read.All." - }, - "adminConsent": { - "title": "Conceder consentimento de administrador", - "body": "De volta em Permissões de API, clique em Conceder consentimento de administrador para {tenant} e confirme." - }, - "noteIds": { - "title": "Copiar os IDs do aplicativo", - "body": "Vá para a Visão geral do aplicativo e copie o ID do aplicativo (cliente) e o ID do diretório (tenant). Você também precisa do valor do segredo copiado na etapa 4." - } - }, - "credentialsSection": "Credenciais", - "credentials": { - "title": "Conectar seu tenant do Microsoft 365", - "body": "Insira os detalhes das etapas acima. O UTMStack verifica as credenciais antes de salvar. Você pode adicionar vários grupos de configuração." - }, - "fields": { - "tenantId": { - "label": "ID do Tenant (ID do Diretório)" - }, - "clientId": { - "label": "ID do Cliente (ID do Aplicativo)" - }, - "clientSecret": { - "label": "Segredo do Cliente" - }, - "cloudEnv": { - "label": "Ambiente de nuvem (opcional)", - "hint": "Commercial (padrão), GCC, GCCHigh ou DoD" - } - } - } - }, - "cloud": { - "howItWorksTitle": "Como funciona", - "howItWorksBody": "{{name}} executa completamente dentro do UTMStack — sem agente ou coletor para implantar. Fornece credenciais de API somente leitura e o UTMStack buscará eventos em um cronograma, analisará-os e os ingerirá no Log Explorer.", - "connectionTitle": "Conexão", - "noFields": "Nenhum campo de conexão configurado.", - "testConnection": "Testar conexão", - "save": "Salvar", - "afterTitle": "O que você verá após conectar", - "after1": "O UTMStack realiza um preenchimento inicial de eventos recentes.", - "after2": "A partir de então, os eventos são buscados a cada 1–5 minutos (depende da API).", - "after3": "A integração aparece em Fontes de dados com status atual de busca e atraso.", - "tenants": { - "title": "Grupos de configuração configurados", - "empty": "Ainda não há grupos de configuração. Adicione o primeiro abaixo.", - "loading": "Carregando grupos de configuração…", - "nameLabel": "Nome do grupo de configuração", - "namePlaceholder": "p. ex. acme-prod", - "add": "Adicionar grupo de configuração", - "update": "Atualizar grupo de configuração", - "delete": "Excluir", - "edit": "Editar", - "cancel": "Cancelar", - "editing": "Editando: {{name}}", - "selectFile": "Selecionar arquivo", - "replaceFile": "Substituir arquivo", - "fileLoaded": "Arquivo carregado", - "invalidJson": "Não foi possível ler o arquivo como JSON.", - "createError": "Não foi possível criar o grupo de configuração. Tente novamente.", - "updateError": "Não foi possível atualizar o grupo de configuração. Tente novamente.", - "createSuccess": "Grupo de configuração criado com sucesso.", - "updateSuccess": "Grupo de configuração atualizado com sucesso." - }, - "google": { - "sections": { - "createTopic": { - "title": "1 · Crie um tópico Pub/Sub", - "body": "No console do Google Cloud, abra Pub/Sub → Tópicos e crie um novo tópico. UTMStack receberá eventos por este tópico.", - "docLabel": "Abrir a página de tópicos Pub/Sub" - }, - "createSubscription": { - "title": "2 · Crie uma assinatura", - "body": "Dentro do tópico, crie uma assinatura do tipo Pull. UTMStack obtém mensagens desta assinatura." - }, - "configureSubscription": { - "title": "3 · Configure a assinatura", - "body": "Defina a duração de retenção de mensagens conforme sua tolerância a indisponibilidades (7 dias padrão é suficiente). Mantenha o prazo de confirmação em 10 segundos e expiração em «Nunca expirar»." - }, - "logsRouter": { - "title": "4 · Abra o Logs Router", - "body": "Navegue até Logging → Logs Router e crie um novo sink. Ele encaminha os logs do projeto para o tópico Pub/Sub criado acima." - }, - "sinkDestination": { - "title": "5 · Aponte o sink para o tópico", - "body": "Escolha Tópico Cloud Pub/Sub como destino do sink e selecione o tópico criado. Use filtros de inclusão/exclusão para delimitar o que é encaminhado." - }, - "serviceAccount": { - "title": "6 · Crie uma conta de serviço", - "body": "Abra IAM e administração → Contas de serviço e crie uma nova conta de serviço. Atribua a ela o papel Editor do Pub/Sub para que UTMStack possa ler da assinatura.", - "docLabel": "Abrir a página de contas de serviço" - }, - "serviceAccountKey": { - "title": "7 · Gere uma chave para a conta de serviço", - "body": "Abra a conta de serviço, vá na aba Chaves e adicione uma nova chave. Escolha JSON como tipo de chave." - }, - "downloadKey": { - "title": "8 · Baixe e carregue a chave JSON", - "body": "Salve o arquivo JSON que o Google baixa: seu conteúdo vai no campo «Chave JSON da conta de serviço» abaixo." - } - }, - "fields": { - "projectId": { - "label": "ID do projeto" - }, - "subscription": { - "label": "Nome da assinatura" - }, - "jsonKey": { - "label": "Chave JSON da conta de serviço" - } - }, - "intro": { - "title": "Como funciona", - "body": "O UTMStack lê a atividade de auditoria diretamente do Google Cloud via Pub/Sub. Um sink do Logs Router transmite os logs do seu projeto para um tópico Pub/Sub; o UTMStack executa um puller interno que lê uma assinatura Pull nesse tópico usando uma chave de conta de serviço. Nada é instalado no seu projeto GCP.", - "diagram": { - "source": "Cloud Logging", - "edge1": "Logs Router", - "pubsub": "Pub/Sub", - "pubsubSub": "tópico + assinatura", - "edge2": "coleta", - "utmstackSub": "alertas e correlação" - }, - "note": "Nenhum agente é executado no GCP — o UTMStack coleta mensagens da assinatura Pub/Sub usando a chave JSON da conta de serviço que você fornece abaixo." - }, - "credentials": { - "title": "Configuração Pub/Sub", - "body": "Use os valores coletados acima para configurar o UTMStack. Você pode monitorar mais de um projeto salvando configurações adicionais.", - "mapping": { - "intro": "Referência dos campos", - "projectId": "Project ID — o projeto GCP que contém seu tópico, assinatura e sink", - "subscription": "Nome da assinatura — a assinatura Pull criada na etapa 2", - "jsonKey": "Chave JSON da conta de serviço — o arquivo baixado na etapa 8" - } - } }, - "azure": { - "sections": { - "sharedAccessPolicy": { - "title": "2 · Adicione uma política de acesso compartilhado", - "body": "Abra o Event Hub → Políticas de acesso compartilhado e crie uma nova política apenas com a permissão Listen." - }, - "connectionString": { - "title": "3 · Copie a string de conexão primária", - "body": "Abra a política e copie a string de conexão primária. Tem o formato: Endpoint=sb://...;SharedAccessKeyName=...;SharedAccessKey=..." - }, - "consumerGroup": { - "title": "4 · Crie um consumer group dedicado", - "body": "Abra o Event Hub → Consumer groups e crie um novo para UTMStack. Não reutilize $Default — dê ao UTMStack seu próprio grupo para que os checkpoints não colidam com outros consumers.", - "warn": "Crie um grupo de consumidores especificamente para o UTMStack. Não use $Default nem qualquer outro grupo já em uso — reutilizar um grupo de consumidores entre consumidores não relacionados pode causar comportamento inesperado e perda de eventos. Todas as instâncias UTMStack devem compartilhar o mesmo grupo de consumidores para processar eventos em conjunto." - }, - "storageContainer": { - "title": "6 · Crie um container na conta de armazenamento", - "body": "Dentro da conta de armazenamento → Containers, crie um novo container. Anote o nome do container e a string de conexão da conta (Chaves de acesso → String de conexão)." - }, - "eventGrid": { - "title": "7 · Registre o provedor de recursos Event Grid", - "body": "Em Assinaturas → Provedores de recursos, registre Microsoft.EventGrid se ainda não estiver. Isso permite que o Azure encaminhe eventos de nível de assinatura para o seu Event Hub." - }, - "createEventHub": { - "title": "Criar um Event Hub", - "body": "No Azure Portal, crie um namespace de Event Hubs e um Event Hub dentro dele. O UTMStack lerá os eventos desse hub.", - "docLabel": "Início rápido: criar um event hub usando o Azure portal" - }, - "createStorageAccount": { - "title": "Criar uma Storage Account", - "body": "O UTMStack precisa de uma Storage Account para registrar sua posição de leitura. Crie uma na mesma região que o Event Hub.", - "docLabel": "Início rápido: criar uma storage account" - }, - "storageConnection": { - "title": "Copiar a string de conexão da Storage Account", - "body": "Obtenha a string de conexão da Storage Account em: All services → Storage accounts → sua conta → Access keys. O UTMStack a utiliza para armazenar os checkpoints do Event Hub." - }, - "createEventSubscription": { - "title": "Criar uma Event Subscription", - "body": "No painel Events da assinatura, crie um novo evento clicando em Events → Event Subscription." - }, - "configureEventSubscription": { - "title": "Apontar a Event Subscription para o seu Event Hub", - "body": "Configure a Event Subscription para enviar logs ao Event Hub criado na etapa 1." - } - }, - "fields": { - "eventHubConnection": { - "label": "String de conexão do Event Hub" - }, - "consumerGroup": { - "label": "Consumer group" - }, - "storageContainer": { - "label": "Nome do container de armazenamento" - }, - "storageConnection": { - "label": "String de conexão da conta de armazenamento" - } - }, - "intro": { - "title": "Como funciona", - "body": "O UTMStack lê a atividade de auditoria diretamente de um Azure Event Hub. Você configura sua assinatura Azure para transmitir eventos para um Event Hub; o UTMStack executa um puller interno que lê esse hub e registra seu progresso em uma Storage Account. Nada é instalado no seu tenant Azure.", - "diagram": { - "source": "eventos da assinatura", - "edge1": "transmite para", - "eventHub": "Event Hub", - "eventHubSub": "fluxo de eventos", - "edge2": "coleta", - "utmstackSub": "alertas e correlação" - }, - "note": "Nenhum agente é executado no Azure — o UTMStack coleta eventos do Event Hub usando as strings de conexão que você fornece abaixo." - }, - "sampleLabel": "Exemplo de string de conexão:", - "credentials": { - "title": "Configuração do Event Hub", - "body": "Use os dados coletados nas etapas acima para configurar o UTMStack. Você pode adicionar mais de um Event Hub salvando configurações adicionais.", - "mapping": { - "intro": "Referência dos campos", - "eventHubConnection": "String de conexão do Event Hub — valor obtido na etapa 3", - "consumerGroup": "Grupo de consumidores — valor obtido na etapa 4", - "storageContainer": "Nome do container de armazenamento — valor obtido na etapa 6", - "storageConnection": "String de conexão da storage account — valor obtido na etapa 7" - } - } - }, - "aws": { - "intro": { - "title": "Como funciona", - "body": "UTMStack lê a atividade de auditoria diretamente do AWS CloudWatch Logs. O CloudTrail captura chamadas de API e eventos de gerenciamento na sua conta AWS, encaminha-os a um log group do CloudWatch, e UTMStack consulta esse grupo para ingestar e correlacionar eventos.", - "diagram": { - "source": "eventos de API", - "edge1": "CloudTrail", - "cloudwatchSub": "log groups", - "edge2": "consulta", - "utmstackSub": "alertas e correlação" - }, - "note": "Nenhum agente é instalado na AWS — UTMStack extrai os eventos de log usando credenciais IAM somente leitura que você fornece abaixo." - }, - "iamSection": "Configurar Usuário IAM", - "iam": { - "dashboard": { - "title": "Abrir o painel IAM", - "body": "Abra o console da AWS, navegue até o painel IAM e selecione Users." - }, - "addUser": { - "title": "Adicionar um usuário", - "body": "Clique em Add user, insira um nome descritivo e avance para o próximo passo." - }, - "attachPolicy": { - "title": "Vincular a política somente leitura", - "body": "Em Permissions, vincule a política necessária. Selecione CloudWatchLogsReadOnlyAccess para acesso somente leitura ao CloudWatch." - }, - "createUser": { - "title": "Criar o usuário", - "body": "Revise a configuração e clique em Create user para provisionar a conta." - }, - "openUser": { - "title": "Abrir o novo usuário", - "body": "Abra o usuário recém-criado clicando no seu nome para ver detalhes e gerenciar credenciais." - }, - "securityTab": { - "title": "Ir para Security credentials", - "body": "Selecione a aba Security credentials para criar chaves de acesso programático." - }, - "createKey": { - "title": "Criar uma chave de acesso", - "body": "Clique em Create access key e escolha a opção para um aplicativo rodando fora da AWS (acesso programático)." - }, - "confirmKey": { - "title": "Confirmar a criação", - "body": "Confirme a criação da chave de acesso. A AWS irá gerar um Access Key ID e um Secret Access Key." - }, - "downloadKey": { - "title": "Salvar as credenciais", - "body": "Baixe o arquivo de credenciais ou copie o Access Key ID e o Secret Access Key para um local seguro — o Secret Access Key é exibido apenas uma vez." - } - }, - "credentials": { - "title": "Inserir credenciais", - "body": "Cole o Access Key ID e o Secret Access Key obtidos nas etapas anteriores. UTMStack verifica as credenciais na AWS antes de salvar." - }, - "cloudwatchSection": "Configurar AWS CloudWatch", - "cloudwatch": { - "createGroup": { - "title": "Criar um CloudWatch Log Group", - "body": "Abra o console do CloudWatch, escolha Log management e clique em Create log group." - }, - "nameGroup": { - "title": "Nomear o log group e configurar retenção", - "body": "Insira o nome utmstack para o log group e defina a retenção para 1 dia. Clique em Create log group." - }, - "openTrail": { - "title": "Abrir o CloudTrail e criar um trail", - "body": "No console do CloudTrail, clique em Create trail para iniciar a configuração de um novo trail." - }, - "configureTrail": { - "title": "Configurar entrega, validação e integração com CloudWatch", - "body": "No formulário de criação do trail, defina as seguintes opções:", - "items": [ - "Nome e escopo do trail: insira um nome descritivo; ative Apply trail to all accounts in my organization se precisar de coleta em nível de organização.", - "Destino S3: escolha Create new S3 bucket (ou selecione um existente) para entrega de logs brutos.", - "Criptografia: ative Log file SSE-KMS e selecione a chave KMS apropriada.", - "Validação de arquivo de log: ative para garantir a integridade dos logs entregues (recomendado).", - "CloudWatch Logs: ative a entrega ao CloudWatch, selecione Use existing log group e insira o nome exato utmstack.", - "Função IAM: forneça ou crie a função que o CloudTrail usará para escrever no S3 e publicar no CloudWatch." - ] - }, - "eventTypes": { - "title": "Selecionar tipos de eventos", - "body": "Ative as categorias de eventos necessárias para monitoramento e auditoria.", - "management": { - "label": "1 · Eventos de gerenciamento", - "body": "Ative Management events e selecione All para registrar toda atividade de API que gerencia recursos da AWS (criar, atualizar, excluir)." - }, - "data": { - "label": "2 · Eventos de dados", - "body": "Adicione um Data event. Escolha S3 e selecione Log all events para capturar operações em nível de objeto como GetObject e PutObject." - }, - "network": { - "label": "3 · Eventos de atividade de rede", - "body": "Na seção Network Activities adicione pelo menos um serviço (ex. ec2.amazonaws.com) e ative Log all events." - } - }, - "review": { - "title": "Revisar e criar o trail", - "body": "Na tela Configure event aggregation aceite os padrões (ou ajuste se necessário). Revise todas as configurações e clique em Create trail." - } - }, - "fields": { - "accessKeyId": { - "label": "ID da chave de acesso da AWS" - }, - "secretAccessKey": { - "label": "Chave de acesso secreta da AWS" - }, - "region": { - "label": "Região padrão da AWS" - }, - "logGroupName": { - "label": "Nome do log group" - } - } - }, - "crowdstrike": { - "intro": { - "title": "Como funciona", - "body": "O UTMStack lê detecções e atividade de auditoria diretamente da API de Event Streams do CrowdStrike Falcon. Você cria um cliente de API no Falcon com escopo de Event Streams; o UTMStack executa um puller interno que transmite eventos usando essas credenciais. Nada é instalado nos seus endpoints ou no Falcon.", - "diagram": { - "source": "detecções e eventos", - "edge1": "Event Streams API", - "api": "Falcon API", - "apiSub": "fluxo de eventos", - "edge2": "coleta", - "utmstackSub": "alertas e correlação" - }, - "note": "Nenhum agente é implantado pelo UTMStack — ele coleta eventos do Falcon usando as credenciais de cliente de API somente leitura que você fornece abaixo." - }, - "sections": { - "apiClients": { - "title": "Abrir API Clients and Keys", - "body": "No console Falcon, abra o menu (ícone de hambúrguer, canto superior esquerdo) e vá para Support and resources → API Clients and Keys." - }, - "createClient": { - "title": "Criar um novo cliente de API", - "body": "Clique em Create API Client para iniciar uma nova definição de cliente." - }, - "scopes": { - "title": "Nomear o cliente e conceder escopo de Event Streams", - "body": "Dê ao cliente um nome descritivo (o UTMStack o usa para identificar a fonte de eventos) e selecione os escopos de API necessários para Event Streams. Clique em Create para gerar as credenciais." - }, - "recordCredentials": { - "title": "Registrar as credenciais", - "body": "Copie o Client ID, o Client Secret e a Base URL para a sua região CrowdStrike. O segredo é exibido apenas uma vez — armazene-o com segurança. Você colará os três no formulário abaixo." - } - }, - "credentials": { - "title": "Configuração do cliente de API", - "body": "Use as credenciais das etapas acima para configurar o UTMStack. Você pode adicionar mais de um cliente CrowdStrike salvando configurações adicionais.", - "mapping": { - "intro": "Referência dos campos", - "appName": "Nome do app — o nome descritivo do cliente da etapa 3 (identifica a fonte de eventos)", - "clientId": "Client ID — valor registrado na etapa 4", - "clientSecret": "Client Secret — valor registrado na etapa 4 (exibido apenas uma vez)", - "cloudRegionUrl": "Base URL — o endpoint da sua região, ex.: https://api.crowdstrike.com (us-1), https://api.us-2.crowdstrike.com (us-2), https://api.eu-1.crowdstrike.com (eu-1)" - } - }, - "fields": { - "appName": { - "label": "Nome do app" - }, - "clientId": { - "label": "Client ID" - }, - "clientSecret": { - "label": "Client Secret" - }, - "cloudRegionUrl": { - "label": "Base URL (região da nuvem)" + "alerts": { + "empty": "Nenhum alerta vinculado a este incidente.", + "remove": "Desvincular alerta", + "removeConfirm": "Desvincular “{{name}}” deste incidente?", + "removed": "Alerta desvinculado", + "removeError": "Não foi possível desvincular o alerta", + "loadingAlert": "A carregar alerta…", + "alertGone": "Este alerta já não está no armazenamento — a retenção pode tê-lo removido.", + "alertFailed": "Não foi possível carregar o alerta.", + "openInAlerts": "Abrir em Alertas" + }, + "notes": { + "empty": "Ainda sem notas.", + "add": "Adicionar nota", + "addError": "Não foi possível adicionar a nota", + "placeholder": "Escreva uma nota…" + }, + "history": { + "empty": "Ainda sem histórico." + }, + "toast": { + "statusChanged": "Status do incidente atualizado", + "statusError": "Não foi possível alterar o status", + "exportFailed": "Falha ao exportar o CSV" + }, + "assign": { + "assign": "Atribuir", + "search": "Buscar usuários…", + "unassign": "Remover atribuição", + "noUsers": "Sem usuários", + "assigned": "Atribuído a {{user}}", + "unassigned": "Incidente sem atribuição", + "error": "Não foi possível alterar o responsável", + "custom": "Atribuir personalizado", + "customPlaceholder": "Digite um login…" + }, + "action": { + "INCIDENT_CREATED": "Incidente criado", + "INCIDENT_ALERT_ADD": "Alertas adicionados", + "INCIDENT_ALERT_STATUS_CHANGED": "Estado dos alertas alterado", + "INCIDENT_STATUS_CHANGE": "Estado alterado", + "INCIDENT_NOTE_ADD": "Nota adicionada", + "INCIDENT_NOTE_CHANGE": "Nota editada", + "INCIDENT_ASSIGNED": "Atribuição alterada" + }, + "create": { + "title": "Criar incidente", + "stepIndicator": "Etapa {{current}} de {{total}}", + "selectedCount": "{{count}} alertas selecionados", + "submit": "Criar", + "success": "Incidente criado", + "error": "Não foi possível criar o incidente", + "details": { + "nameLabel": "Nome", + "namePlaceholder": "Título curto e descritivo", + "descriptionLabel": "Descrição", + "descriptionPlaceholder": "Contexto, escopo, notas iniciais…" } - } } - }, - "custom": { - "whenTitle": "Quando usar isso", - "whenBody": "Quando sua fonte não está no catálogo. Encaminhe syslog ou JSON arbitrário para o UTMStack e defina um analisador para normalizar campos.", - "endpointsTitle": "Endpoints", - "syslogUdp": "Syslog (UDP)", - "syslogTls": "Syslog (TLS)", - "httpJson": "HTTP / JSON", - "payloadTitle": "Exemplo de payload JSON", - "parserTitle": "Defina o analisador", - "parserBody": "Os eventos recebidos são armazenados sob o tipo de dado {{dataType}}. Adicione um filtro de parsing para ele de modo que o payload bruto seja mapeado em campos estruturados e, em seguida, crie regras de alerta.", - "openEditor": "Abrir editor do analisador", - "powershellLabel": "PowerShell (Executar como administrador)", - "linuxLabel": "Linux — bash", - "macosLabel": "macOS — bash", - "exampleLabel": "Exemplo de destino syslog em {{name}}:", - "intro": { - "title": "Como funciona", - "body": "Uma integração personalizada ingere logs de qualquer fonte não coberta pelos módulos integrados. Você instala o UTMStack Collector, registra um listener para seus dados com o protocolo de sua escolha e aponta sua fonte para ele.", - "note": "Escolha abaixo o protocolo que sua fonte pode enviar (syslog UDP/TCP/TLS, ou HTTP/HTTPS para JSON) — o Collector cria o tipo de dado automaticamente." - }, - "diagram": { - "source": "Sua fonte", - "sourceSub": "qualquer app ou dispositivo", - "forwarder": "Collector", - "ingests": "ingere", - "utmstackSub": "alertas e correlação" - }, - "choose": { - "title": "Escolher protocolo e porta", - "body": "Selecione como sua fonte envia dados e a porta que o Collector deve escutar, depois execute o comando de ativação no host do Collector.", - "portLabel": "Porta de escuta", - "tlsFirst": "Primeiro, carregue seu certificado e chave TLS no Collector:", - "enableLabel": "Em seguida, ative a integração:", - "authNote": "Para exigir autenticação, adicione --auth bearer (token) ou --auth hmac — o Collector imprime um token para usar no cabeçalho Authorization." - }, - "send": { - "title": "Apontar sua fonte para o Collector", - "bodyNetwork": "Configure sua fonte para enviar syslog {{proto}} para {{host}}:{{port}}. A maioria dos dispositivos possui uma configuração de syslog remoto ou encaminhamento de logs para isso.", - "bodyHttp": "Envie seus eventos como JSON via HTTP POST para {{endpoint}}. O corpo de cada requisição é um evento JSON:", - "httpBindNote": "O listener HTTP/HTTPS vincula-se a 127.0.0.1 (o host do Collector) por padrão, portanto envie requisições de um app em execução nesse host — ou coloque um proxy reverso à frente. Para fontes remotas, use syslog (UDP/TCP/TLS)." - }, - "manualCommand": { - "title": "Optional — Enable via the command line instead", - "intro": "Prefer the terminal? SSH into the Collector host and run the command below — it matches whatever protocol and port you have selected above." - } - }, - "remoteEnable": { - "title": "Ativar esta integração remotamente", - "body": "Escolha um Collector, selecione o protocolo e a porta, depois ative a integração — sem necessidade de SSH.", - "noPermission": "Você não tem permissão para gerenciar integrações remotas. Peça a um administrador para conceder a permissão integrations.write.", - "loadingCollectors": "Carregando Collectors…", - "noCollectors": "Nenhum Collector foi registrado ainda. Instale um acima para ativar integrações remotamente.", - "forwarderOffline": "Este Collector está offline e não pode receber alterações de configuração agora.", - "legendOnline": "{{count}} online", - "legendOffline": "{{count}} offline", - "legendTotal": "{{count}} total", - "forwarderLabel": "Collector", - "protoLabel": "Protocolo", - "portLabel": "Porta", - "currentStateLoading": "Verificando configuração atual…", - "currentlyEnabled": "Atualmente: ativada · {{proto}} · porta {{port}}", - "currentlyDisabled": "Atualmente: desativada · {{proto}} · porta {{port}}", - "authLabel": "Autenticação", - "authNone": "Nenhuma", - "authBearer": "Token Bearer", - "authHmac": "Assinatura HMAC", - "pathLabel": "Caminho", - "signatureHeaderLabel": "Cabeçalho de assinatura", - "certTitle": "Certificado TLS", - "certLoading": "Verificando status do certificado…", - "certLoaded": "Um certificado válido já está carregado neste Collector.", - "certMissing": "Nenhum certificado carregado ainda — envie um para ativar este protocolo.", - "certInvalid": "O certificado carregado é inválido: {{error}}", - "certPemLabel": "Certificado", - "keyPemLabel": "Chave privada", - "caPemLabel": "Certificado CA", - "uploadCertsButton": "Enviar certificado", - "certUploadSuccess": "Certificado enviado.", - "certUploadError": "Falha ao enviar o certificado.", - "certReadError": "Não foi possível ler o(s) arquivo(s) selecionado(s).", - "enableButton": "Ativar integração", - "disableButton": "Desativar integração", - "enableSuccess": "Integração ativada.", - "disableSuccess": "Integração desativada.", - "enableError": "Falha ao atualizar a integração.", - "secretWarning": "Armazene este token com segurança — não será exibido novamente.", - "sendToInstance": "Enviar para a instância", - "enterpriseFeature": "Este é um recurso Enterprise.", - "addCollector": "Adicionar Collector", - "addApiKey": "Adicionar chave de API", - "apiKeyLabel": "Chave de API", - "apiKeyHint": "Primeiro você precisará de uma chave de API.", - "apiKeyPlaceholder": "Selecionar uma chave de API", - "apiKeyAddNew": "Adicionar chave de API…", - "apiKeyNone": "Nenhuma chave de API ainda", - "forwarderNoRemoteControl": "Este forwarder foi instalado com o controlo remoto desativado. Ignora a configuração enviada daqui, e isso só pode ser alterado na própria máquina." - } - }, - "codeBlock": { - "copy": "Copiar", - "copied": "Copiado" - }, - "createDrawer": { - "title": "Nova integração personalizada", - "moduleName": "Nome do módulo", - "moduleNameHint": "Identificador único. Sem espaços.", - "moduleNamePlaceholder": "minha-app-personalizada", - "prettyName": "Nome para exibição", - "prettyNamePlaceholder": "Minha App Personalizada", - "dataType": "Tipo de dados", - "dataTypePlaceholder": "Identificador único para este tipo de dados", - "icon": "Ícone", - "iconHint": "PNG, SVG, JPEG, GIF ou WEBP. Máximo 3MB. Usado como logo da integração.", - "iconPreview": "Visualização do ícone", - "dataTypeExists": "Este tipo de dados já existe", - "invalidFileType": "O ícone deve ser um arquivo de imagem válido (PNG, JPEG, SVG, GIF, WEBP)", - "fileTooLarge": "O ícone não deve exceder 3MB", - "fileReadError": "Falha ao ler o arquivo", - "cancel": "Cancelar", - "create": "Criar integração", - "creating": "Criando…", - "editTitle": "Editar integração", - "save": "Salvar", - "saving": "Salvando…", - "currentIcon": "Ícone atual — faça upload de um arquivo para substituí-lo", - "name": "Nome da integração", - "namePlaceholder": "ex.: Acme Firewall", - "description": "Descrição", - "descriptionPlaceholder": "O que esta integração ingere e por quê (opcional)", - "identifierHint": "Armazenado como \"{{id}}\" (derivado do nome)", - "nameTaken": "Esse nome de integração não pode ser usado — já existe uma integração com esse identificador.", - "removeIcon": "Remover ícone", - "defaultIconNote": "Ícone padrão — envie um arquivo para usar o seu próprio." - }, - "toast": { - "created": "Integração criada", - "updated": "Integração atualizada", - "updateError": "Falha ao atualizar a integração" - }, - "delete": { - "title": "Excluir integração", - "confirm": "Excluir esta integração?", - "yes": "Excluir", - "no": "Cancelar", - "deleted": "Integração excluída", - "error": "Falha ao excluir a integração" - }, - "modules": { - "WINDOWS_AGENT": "Colete atividades do sistema Windows, segurança e logs de eventos por meio do agente leve UTMStack instalado em cada host.", - "LINUX_AGENT": "Colete logs de sistema, autenticação e auditoria do Linux por meio do agente leve UTMStack instalado em cada host.", - "MACOS": "Colete atividade de logs de sistema e segurança do macOS nos endpoints Apple Mac por meio do agente leve UTMStack.", - "VMWARE": "Ingira syslog do hipervisor VMware ESXi para que a atividade e os eventos do host de virtualização sejam monitorados no UTMStack.", - "NETFLOW": "Ingira registros NetFlow de roteadores e switches para monitorar padrões de tráfego de rede e detectar anomalias.", - "AWS_IAM_USER": "Ingira atividade de conta AWS e chamadas de API via CloudTrail e CloudWatch para auditar uso, acesso e alterações na nuvem.", - "AZURE": "Ingira logs de plataforma e atividade do Microsoft Azure para monitorar cargas de trabalho, identidade e alterações de recursos na nuvem.", - "O365": "Ingira logs de auditoria do Microsoft 365 no Exchange, Teams, SharePoint e OneDrive para monitorar a atividade de usuários e administradores.", - "O365_GRAPH": "Ingesta eventos de segurança do Microsoft Graph — alertas, incidentes, auditoria do diretório, sign-ins, detecções de risco e logs de auditoria do Purview — para monitorar identidade e atividade de ameaças no seu tenant.", - "GCP": "Ingira logs de auditoria e atividade do Google Cloud Platform para monitorar computação, armazenamento e identidade entre projetos.", - "KASPERSKY": "Ingira detecções e telemetria de endpoint do Kaspersky Security Center para correlacionar atividade de malware na rede.", - "ESET": "Ingira detecções e telemetria de endpoint do ESET PROTECT para correlacionar a defesa multicamadas contra malware em todo o ambiente.", - "BITDEFENDER": "Ingira detecções e telemetria de endpoint do Bitdefender GravityZone para correlacionar ameaças em dispositivos corporativos.", - "SENTINEL_ONE": "Ingira detecções de endpoint e telemetria comportamental do SentinelOne para correlacionar e investigar ameaças em escala.", - "SOPHOS": "Ingira detecções do Sophos Central em endpoint, servidor, firewall e e-mail para correlacionar ameaças em um único lugar.", - "CROWDSTRIKE": "Ingira detecções de endpoint e carga de trabalho do CrowdStrike Falcon para correlacionar atividade de ameaças nativas da nuvem no UTMStack.", - "CISCO": "Ingira logs de tráfego, VPN e ameaças do firewall Cisco ASA para monitorar a segurança de perímetro e o acesso no UTMStack.", - "MERAKI": "Ingira syslog do firewall e appliance de segurança Cisco Meraki para monitorar tráfego de rede e ameaças gerenciados na nuvem.", - "FIRE_POWER": "Ingira logs do NGFW e IPS Cisco Firepower para monitorar tentativas de intrusão e atividade de ameaças no perímetro.", - "CISCO_SWITCH": "Ingira syslog e telemetria de switches Cisco para monitorar desempenho de rede, alterações de configuração e segurança.", - "FORTIGATE": "Ingira logs de tráfego e ameaças do NGFW Fortinet FortiGate para monitorar a segurança de perímetro e a atividade de rede.", - "FORTIWEB": "Ingira logs do WAF Fortinet FortiWeb para monitorar ataques a aplicações web e proteger serviços e APIs expostos.", - "SOPHOS_XG": "Ingira logs do firewall Sophos XG com filtragem web, IPS e VPN para monitorar tráfego de rede e ameaças.", - "PALO_ALTO": "Ingira logs de tráfego e ameaças do NGFW Palo Alto Networks para monitorar o uso de aplicações e a segurança de perímetro.", - "SONIC_WALL": "Ingira logs de tráfego e ameaças do NGFW SonicWall para monitorar a segurança de perímetro e a atividade de rede no UTMStack.", - "PFSENSE": "Ingira logs de firewall e roteador do pfSense com gerenciamento unificado de ameaças para monitorar tráfego de rede e ameaças.", - "MIKROTIK": "Ingira logs de firewall, roteamento e wireless do MikroTik RouterOS para monitorar a atividade de rede e configurações.", - "AIX": "Colete logs de sistema, segurança e auditoria do IBM AIX Unix para monitorar a atividade em plataformas IBM Power no UTMStack.", - "AS_400": "Colete journals de sistema e auditoria do IBM AS/400 (IBM i) para monitorar a atividade de usuários em plataformas midrange OS/400.", - "ORACLE": "Ingira logs de auditoria do Oracle Database para monitorar consultas, acessos e atividade privilegiada nos bancos de dados.", - "SURICATA": "Ingira alertas e eventos de rede do Suricata IDS/IPS para detectar intrusões e tráfego malicioso na rede.", - "DECEPTIVE_BYTES": "Ingira alertas do Deceptive Bytes da sua plataforma ativa de decepção em endpoints para identificar atividade de atacantes precocemente.", - "GITHUB": "Ingira logs de auditoria do GitHub para monitorar acesso a repositórios, alterações de código e atividade da organização para segurança do código-fonte.", - "UTMSTACK": "Ingira a própria telemetria SIEM e XDR do UTMStack para monitorar a saúde da plataforma, atividade interna e eventos de autoauditoria.", - "NGINX": { - "name": "Nginx", - "description": "Ingira os logs de acesso e erro do Nginx para monitorar a atividade do servidor web, o tráfego do proxy reverso e as requisições dos clientes." - }, - "APACHE": { - "name": "Apache", - "description": "Ingira os logs de acesso e erro do Apache HTTPD para monitorar a atividade do servidor web e as requisições dos clientes." - }, - "APACHE2": { - "name": "Apache2", - "description": "Ingira os logs do servidor web Apache2 (HTTPD) para monitorar o processamento de requisições, erros e o acesso em hosts Linux." - }, - "IIS": { - "name": "IIS", - "description": "Ingira a atividade de acesso e os arquivos de log do Internet Information Services (IIS) para monitorar o serviço web do Windows." - }, - "MYSQL": { - "name": "MySQL", - "description": "Ingira a atividade de logs do MySQL para monitorar consultas, autenticação e o acesso ao repositório de dados." - }, - "POSTGRESQL": { - "name": "PostgreSQL", - "description": "Ingira os logs do PostgreSQL para monitorar consultas, acesso e a atividade em seus repositórios de dados." - }, - "MONGODB": { - "name": "MongoDB", - "description": "Ingira a atividade de logs do MongoDB para monitorar o acesso ao banco de dados documental, as consultas e o comportamento do aplicativo." - }, - "REDIS": { - "name": "Redis", - "description": "Ingira a atividade de logs e telemetria do Redis para monitorar o uso do repositório de dados em memória e as cargas de trabalho em tempo real." - }, - "ELASTICSEARCH": { - "name": "Elasticsearch", - "description": "Ingira os logs do Elasticsearch para monitorar o mecanismo de busca e análise e suas cargas de trabalho do aplicativo." - }, - "LOGSTASH": { - "name": "Logstash", - "description": "Ingira os logs das pipelines do Logstash para monitorar a pipeline de processamento de dados e suas transformações de eventos." - }, - "KIBANA": { - "name": "Kibana", - "description": "Ingira os logs do Kibana para monitorar a camada de visualização e exploração de dados e seu uso." - }, - "KAFKA": { - "name": "Apache Kafka", - "description": "Ingira os logs do Apache Kafka para monitorar as pipelines de streaming em tempo real, os brokers e o fluxo de mensagens." - }, - "NATS": { - "name": "NATS", - "description": "Ingira os logs de mensageria do NATS para monitorar o bus de mensagens, a conectividade e a entrega de eventos." - }, - "HAPROXY": { - "name": "HAProxy", - "description": "Ingira os logs do HAProxy para monitorar o balanceamento de carga, o tráfego do proxy e a disponibilidade da rede." - }, - "TRAEFIK": { - "name": "Traefik", - "description": "Ingira os logs do Traefik para monitorar o roteamento, o balanceamento de carga e o tráfego do proxy entre as cargas de trabalho." - }, - "OSQUERY": { - "name": "osquery", - "description": "Ingira os logs do OsQuery para monitorar o estado do endpoint, as consultas e o inventário do sistema por meio de requisições no estilo SQL." - }, - "SYSLOG": { - "name": "Syslog", - "description": "Envie syslog (RFC 5424/3164) de qualquer dispositivo ou aplicação para o endpoint do coletor, para a ingestão centralizada de logs." - }, - "JSON": { - "name": "JSON Input", - "description": "Envie cargas de logs em JSON para o endpoint de ingestão, para a captura estruturada de eventos de aplicativos e scripts." - }, - "WINDOWS_SQL_SERVER": { - "name": "SQL Server Event Logs", - "description": "Collect Microsoft SQL Server audit and event records through the Windows Event Log and UTMStack agent." - }, - "WINDOWS_FILE_AUDITING": { - "name": "Windows File Access Auditing", - "description": "Collect Windows file access audit events through the Windows Event Log and UTMStack agent." - }, - "ELASTICsearch": { - "name": "ELASTICsearch", - "description": "Ingesta los registros de Elasticsearch para monitorear el motor de búsqueda y análisis y sus cargas de trabajo de aplicación." - } }, - "edit": { - "title": "Editar integração" - }, - "allCategories": "Todas as categorias", - "customOnly": "Personalizado" - }, - "dataProcessing": { - "title": "Processamento de dados", - "subtitle": "Estatísticas de ingestão e processamento: eventos recebidos, descartados por etapa, e as principais fontes e tipos.", - "ingestion": { - "title": "Ingestão", - "last24h": "últimas 24 horas", - "noData": "Sem dados nesta janela.", - "loadError": "Não foi possível carregar as estatísticas de ingestão.", - "groupBy": { - "dataSource": "Por fonte de dados", - "dataType": "Por tipo de dado" - }, - "status": { - "received": "Recebidos", - "parsing_dropped": "Descartados (parsing)", - "analysis_dropped": "Descartados (análise)", - "correlation_dropped": "Descartados (correlação)", - "all": "Todos os eventos" - } - }, - "filters": { - "title": "Filtros", - "new": "Novo filtro", - "search": "Pesquisar por caminho…", - "refresh": "Atualizar", - "retry": "Tentar novamente", - "empty": "Nenhum filtro corresponde.", - "loadError": "Não foi possível carregar os filtros.", - "toggleError": "Não foi possível alterar o estado do filtro", - "system": "Sistema", - "custom": "Personalizado", - "systemReadonly": "Os filtros do sistema são somente leitura", - "view": "Ver", - "edit": "Editar", - "ownership": { - "all": "Todos", + "parsingFilters": { + "title": "Pipelines", + "subtitle": "Pipelines YAML aplicados aos logs enquanto são processados na ingestão.", + "new": "Novo pipeline", + "search": "Buscar pipelines…", + "refresh": "Atualizar", + "view": "Ver", "system": "Sistema", - "custom": "Personalizados" - }, - "state": { - "all": "Todos", - "active": "Ativos", - "inactive": "Inativos" - }, - "col": { - "filter": "Filtro", - "type": "Tipo", - "active": "Ativo", - "actions": "Ações" - }, - "pageInfo": "{{from}}–{{to}} de {{count}}" - }, - "editor": { - "createTitle": "Novo filtro", - "editTitle": "Editar filtro", - "viewTitle": "Ver filtro", - "relPath": "Caminho", - "relPathHint": "Pasta + arquivo, ex. syslog/meu-filtro.yaml", - "content": "Pipeline (YAML)", - "contentHint": "As etapas rodam em ordem: grok, rename, delete, plugins dynamic, …", - "save": "Salvar", - "saving": "Salvando…", - "saved": "Filtro salvo", - "saveError": "Não foi possível salvar o filtro", - "cancel": "Cancelar", - "delete": "Excluir", - "deleteConfirm": "Excluir este filtro?", - "deleted": "Filtro excluído", - "deleteError": "Não foi possível excluir o filtro" - }, - "kpi": { - "received": "Recebidos", - "dropped": "Descartados", - "dropRate": "{{rate}}% de descarte", - "stored": "Armazenados", - "throughput": "Vazão", - "perMin": "{{value}}/min", - "survival": "{{rate}}% mantidos" - }, - "section": { - "overTime": "Eventos ao longo do tempo", - "top": "Top", - "dropReasons": "Motivos de descarte" - }, - "live": { - "auto": "Auto" - }, - "pipeline": { - "title": "Pipeline de ingestão", - "stages": { - "received": "Recebidos", - "parsed": "Analisados (parse)", - "analyzed": "Analisados", - "stored": "Armazenados" - } - }, - "chart": { - "title": "Vazão ao longo do tempo", - "received": "Recebidos", - "dropped": "Descartados" - }, - "donut": { - "title": "Composição de descartes", - "dropped": "descartados" - }, - "breakdown": { - "title": "Top fontes e tipos", - "bars": "Barras", - "treemap": "Treemap", - "showAll": "Ver todos os {{count}}", - "showLess": "Ver menos", - "lastSeen": "Visto por último", - "ago": "há {{time}}" - } - }, - "datasources": { - "limitBanner": { - "title": "Limite de datasources excedido.", - "message": "Você tem {{count}} datasources, mas sua licença cobre {{limit}}. Os logs dos datasources além do limite estão sendo descartados.", - "cta": "Gerenciar licença", - "dismiss": "Dispensar" - }, - "title": "Fontes de dados", - "total": "{{count}} no total", - "subtitle": "Agentes, integrações e fontes diretas que enviam eventos. O status é derivado da última vez que cada fonte foi vista.", - "connectSource": "Conectar uma fonte", - "loading": "Carregando fontes de dados…", - "loadFailed": "Não foi possível carregar as fontes de dados.", - "retry": "Tentar novamente", - "none": "Nenhuma fonte corresponde a esta visão.", - "ingestion": { - "title": "Ingestão", - "received": "eventos recebidos", - "none": "Sem ingestão nas últimas 24 horas.", - "ago24h": "há 24h", - "now": "agora" - }, - "usage": { - "title": "Fontes de dados", - "ofUnlimited": "de ilimitado", - "ofLimit": "de {{limit}}", - "overLimit": "Acima do limite licenciado — os dados além do limite estão em risco.", - "configured": "configuradas" - }, - "tabs": { - "all": "Todas", - "agent": "Agentes", - "puller": "Integrações", - "direct": "Diretas", - "offline": "Offline" - }, - "toolbar": { - "searchPlaceholder": "Buscar por nome…", - "list": "Lista", - "cards": "Cartões", - "refresh": "Atualizar" - }, - "labels": { - "filteredBy": "Filtrado por label", - "add": "Adicionar label…", - "addFirst": "Adicionar um label…", - "hint": "Digite um label e pressione Enter para adicioná-lo. As alterações são salvas automaticamente." - }, - "status": { - "live": "Ativa", - "idle": "Inativa", - "offline": "Offline" - }, - "kind": { - "agent": "Agente", - "puller": "Integração", - "direct": "Direta" - }, - "cols": { - "source": "Fonte", - "type": "Tipo", - "status": "Status", - "events24h": "Eventos 24h", - "lastSeen": "Visto por último" + "user": "Personalizado", + "loading": "Carregando pipelines…", + "loadError": "Não foi possível carregar os pipelines.", + "retry": "Tentar novamente", + "empty": "Nenhum pipeline corresponde a esta vista.", + "tabs": { + "all": "Todos", + "active": "Ativos", + "inactive": "Inativos", + "system": "Sistema", + "user": "Personalizados" + }, + "cols": { + "filter": "Pipeline", + "type": "Tipo", + "active": "Ativo", + "dataTypes": "Tipos de dado", + "order": "Ordem", + "moveUp": "Mover para cima", + "moveDown": "Mover para baixo", + "actions": "Ações" + }, + "editor": { + "titleNew": "Novo pipeline", + "titleEdit": "Editar pipeline", + "titleSystem": "Pipeline (sistema)", + "name": "Nome", + "namePlaceholder": "Meu pipeline personalizado", + "nameHint": "Será salvo como {{file}}", + "namePending": "Escolha um nome — ele será o nome do arquivo.", + "content": "Conteúdo (pipeline YAML)", + "contentHint": "Uma definição válida em pipeline: YAML.", + "readOnly": "Pipeline do sistema — somente leitura. Você só pode ativá-lo ou desativá-lo.", + "save": "Salvar", + "saving": "Salvando…", + "delete": "Excluir", + "confirmDelete": "Confirmar exclusão", + "cancel": "Cancelar", + "test": "Test" + }, + "toast": { + "saved": "Pipeline salvo", + "saveError": "Falha ao salvar o pipeline", + "deleted": "Pipeline excluído", + "deleteError": "Falha ao excluir o pipeline", + "activateError": "Falha ao alterar o estado do pipeline", + "nameRequired": "O nome é obrigatório", + "contentRequired": "O conteúdo é obrigatório", + "orderError": "Falha ao reordenar o pipeline" + }, + "visual": { + "visualTab": "Visual", + "codeTab": "Código", + "codeOnly": "Mude para Código — este conteúdo não pode ser exibido visualmente.", + "cantParse": "Não foi possível abrir o editor visual: {{error}}", + "dataTypes": "Tipos de dado", + "steps": "Etapas", + "noSteps": "Ainda não há etapas.", + "addStep": "Adicionar etapa:", + "removeStep": "Remover etapa", + "moveUp": "Mover para cima", + "moveDown": "Mover para baixo", + "whereHint": "condição opcional (CEL)", + "addValue": "Adicionar valor", + "addPattern": "Adicionar padrão", + "rawHint": "Este processor é editado como YAML direto.", + "rawNotMap": "Deve ser um conjunto de campos chave: valor.", + "dataTypesPick": "Escolher tipos de dado", + "dataTypesSearch": "Buscar tipos de dado…", + "dataTypesNone": "Sem tipos de dado", + "dataTypesAdd": "Adicionar \"{{value}}\"", + "insertPattern": "Inserir padrão regex", + "patternSearch": "Buscar padrões…", + "patternNone": "Sem padrões", + "newPattern": "Novo padrão…", + "createInsert": "Criar e inserir", + "patternCreated": "Padrão \"{{name}}\" criado", + "patternCreateError": "Falha ao criar o padrão", + "patternIdInvalid": "O ID deve começar com letra ou _ e usar apenas letras, dígitos ou _", + "patternDefRequired": "A definição é obrigatória", + "parameters": "Parâmetros", + "paramsKey": "Chave", + "paramsValue": "Valor", + "entry": "Entrada {{n}}", + "order": "ordem {{n}}", + "orderLabel": "Ordem", + "removeEntry": "Remover entrada", + "addEntry": "Adicionar entrada de pipeline", + "collapse": "Recolher", + "expand": "Expandir", + "splitHint": "Vacío equivale a un espacio por defecto — en el YAML siempre aparece como fieldSplit: \" \"." + }, + "allDataTypes": "Todos os tipos de dado", + "testPipeline": "Test pipeline" + }, + "alertingRules": { + "title": "Regras de Alerta", + "subtitle": "Regras de correlação que transformam eventos em alertas. Ative, ajuste ou crie as suas.", + "new": "Nova regra", + "refresh": "Atualizar", + "empty": "Nenhuma regra corresponde.", + "loadError": "Não foi possível carregar as regras.", + "retry": "Tentar novamente", + "deleteConfirm": "Excluir a regra “{{name}}”?", + "adversary": { + "origin": "Origem", + "target": "Destino" + }, + "state": { + "active": "Ativa", + "inactive": "Inativa" + }, + "owner": { + "system": "Sistema", + "custom": "Personalizada" + }, + "toolbar": { + "search": "Buscar regras…", + "allCategories": "Todas as categorias", + "allAdversaries": "Todos os adversários", + "allStates": "Todos os estados", + "allOwners": "Todas as origens", + "allDataTypes": "Todos os tipos" + }, + "table": { + "name": "Regra", + "category": "Categoria", + "technique": "Técnica", + "adversary": "Adversário", + "impact": "Impacto", + "active": "Ativa", + "dataTypes": "Tipos de dado", + "selectAll": "Selecionar tudo", + "selectRow": "Selecionar {{name}}" + }, + "export": { + "all": "Exportar tudo", + "selected": "Exportar ({{count}})", + "error": "Não foi possível exportar as regras" + }, + "view": { + "description": "Descrição", + "details": "Detalhes", + "impact": "Impacto (C·I·D)", + "dataTypes": "Tipos de dado", + "updated": "Atualizada", + "relPath": "Caminho", + "definition": "Condição (CEL)", + "correlationSteps": "Passos de correlação", + "correlation": "Correlação", + "groupBy": "Agrupar por", + "deduplicateBy": "Deduplicar por", + "references": "Referências" + }, + "editor": { + "createTitle": "Nova regra", + "edit": "Editar", + "delete": "Excluir", + "export": "Exportar", + "cancel": "Cancelar", + "save": "Salvar", + "metadata": "Metadados", + "name": "Nome", + "confidentiality": "Confidencialidade", + "integrity": "Integridade", + "availability": "Disponibilidade", + "dataTypes": "Tipos de dado", + "dataTypesHint": "separados por vírgula", + "activeOnSave": "Ativa", + "definitionSection": "Definição", + "where": "Condição (CEL)", + "whereHint": "Expressão CEL avaliada por evento", + "correlationSteps": "Passos de correlação", + "correlationStepsHint": "array JSON", + "jsonArray": "array JSON", + "nameRequired": "O nome é obrigatório", + "definitionRequired": "A condição é obrigatória", + "invalidJson": "Um campo da definição tem JSON inválido", + "addStep": "Adicionar passo de correlação", + "step": "Passo {{n}}", + "removeStep": "Remover passo", + "indexPattern": "Padrão de índice", + "within": "Janela", + "count": "Quantidade", + "conditions": "Condições", + "field": "Campo", + "value": "Valor", + "addCondition": "Adicionar condição", + "orGroup": "Grupo Or {{n}}", + "addOr": "Adicionar grupo Or", + "removeOr": "Remover", + "fieldsHint": "nomes de campo", + "referencesHint": "URLs", + "visual": "Visual", + "code": "Código", + "dataTypesPick": "Selecionar…", + "dataTypesSearch": "Buscar tipos de dado…", + "dataTypesNone": "Sem tipos de dado", + "visualTab": "Visual", + "codeTab": "Código", + "yamlError": "Não foi possível aplicar o YAML: {{error}}", + "test": "Test" + }, + "toast": { + "activated": "Regra ativada", + "deactivated": "Regra desativada", + "toggleError": "Não foi possível alterar o estado da regra", + "deleted": "Regra excluída", + "deleteError": "Não foi possível excluir a regra", + "created": "Regra criada", + "saved": "Regra salva", + "saveError": "Não foi possível salvar a regra" + }, + "operator": { + "filter_term": "igual (term)", + "must_not_term": "diferente (term)", + "filter_match": "corresponde (texto)", + "must_not_match": "não corresponde (texto)" + }, + "where": { + "matchPrefix": "Corresponde a", + "all": "todas", + "any": "qualquer", + "matchSuffix": "destas condições:", + "negate": "Negar", + "listHint": "separado por vírgulas", + "advanced": "Esta condição usa CEL avançado — edite no Código ou reconstrua visualmente.", + "and": "E", + "or": "OU" + }, + "celOp": { + "exists": "existe", + "equals": "igual a", + "equalsIgnoreCase": "igual (sem maiús.)", + "contains": "contém", + "oneOf": "é um de", + "containsAll": "contém todos", + "startsWith": "começa com", + "endsWith": "termina com", + "regexMatch": "regex", + "lessThan": "<", + "lessOrEqual": "≤", + "greaterThan": ">", + "greaterOrEqual": "≥", + "inCIDR": "em CIDR", + "isHour": "a hora é", + "isMinute": "o minuto é", + "isDayOfWeek": "o dia é", + "isWeekend": "é fim de semana", + "isWorkDay": "é dia útil", + "isBetweenTime": "hora entre" + }, + "import": { + "button": "Importar", + "error": "Falha na importação", + "resultTitle": "Resultados da importação", + "approved": "Aprovadas", + "rejected": "Rejeitadas", + "done": "Concluído" + }, + "test": "Test" + }, + "regexPatterns": { + "title": "Expressões regulares", + "subtitle": "Expressões regulares reutilizáveis referenciadas pelos filtros de parsing.", + "new": "Novo padrão", + "search": "Buscar padrões…", + "refresh": "Atualizar", + "view": "Ver", + "system": "Sistema", + "user": "Personalizado", + "loading": "Carregando padrões…", + "loadError": "Não foi possível carregar os padrões.", + "retry": "Tentar novamente", + "empty": "Nenhum padrão corresponde a esta visão.", + "tabs": { + "all": "Todos", + "system": "Sistema", + "user": "Personalizados" + }, + "cols": { + "pattern": "Padrão", + "definition": "Definição", + "type": "Tipo" + }, + "editor": { + "titleNew": "Novo padrão", + "patternId": "ID do padrão", + "patternIdHint": "Nome único referenciado pelos filtros.", + "description": "Descrição", + "descriptionPlaceholder": "O que este padrão reconhece (opcional)", + "definition": "Definição (regex)", + "definitionHint": "Uma expressão regular. Pode referenciar outros padrões.", + "readOnly": "Padrão do sistema — somente leitura.", + "save": "Salvar", + "saving": "Salvando…", + "delete": "Excluir", + "confirmDelete": "Confirmar exclusão", + "cancel": "Cancelar" + }, + "toast": { + "saved": "Padrão salvo", + "saveError": "Falha ao salvar o padrão", + "deleted": "Padrão excluído", + "deleteError": "Falha ao excluir o padrão", + "patternIdRequired": "O ID do padrão é obrigatório", + "definitionRequired": "A definição é obrigatória" + } }, - "time": { - "justNow": "agora mesmo", - "minutesAgo": "há {{count}}m", - "hoursAgo": "há {{count}}h", - "daysAgo": "há {{count}}d" + "soar": { + "title": "SOAR", + "subtitle": "Fluxos de resposta automática: as condições combinam um alerta e os comandos rodam no agente.", + "comingSoon": "Em breve", + "console": { + "loading": "Carregando agentes…", + "loadError": "Não foi possível carregar os agentes.", + "pickAgent": "Selecione um agente", + "pickAgentHint": "Escolha um agente da lista para abrir seu console interativo.", + "lockedAgent": "Controlo remoto desativado" + }, + "search": "Buscar fluxos…", + "refresh": "Atualizar", + "new": "Novo fluxo", + "view": "Ver", + "system": "Sistema", + "loading": "Carregando fluxos…", + "loadError": "Não foi possível carregar os fluxos.", + "retry": "Tentar de novo", + "empty": "Nenhum fluxo corresponde a esta visão.", + "templates": { + "title": "Novo fluxo", + "subtitle": "Escolha um modelo de ação ou comece do zero.", + "loading": "Carregando modelos…", + "loadError": "Não foi possível carregar os modelos.", + "empty": "Nenhum modelo disponível.", + "cancel": "Cancelar", + "scratch": "Começar do zero" + }, + "tabs": { + "flows": "Fluxos", + "executions": "Histórico de execuções", + "all": "Todos", + "active": "Ativos", + "inactive": "Inativos", + "system": "Sistema", + "user": "Próprios" + }, + "cols": { + "flow": "Fluxo", + "platform": "Plataforma", + "conditions": "Condições", + "commands": "Comandos", + "active": "Ativo", + "lastRun": "Última execução", + "failedRuns_one": "{{count}} execução falhada", + "failedRuns_other": "{{count}} execuções falhadas" + }, + "operator": { + "IS": "é", + "IS_NOT": "não é", + "CONTAINS": "contém", + "NOT_CONTAINS": "não contém", + "EXISTS": "existe", + "NOT_EXISTS": "não existe", + "START_WITH": "começa com", + "NOT_START_WITH": "não começa com", + "ENDS_WITH": "termina com", + "NOT_ENDS_WITH": "não termina com", + "IS_ONE_OF": "é um de", + "IS_NOT_ONE_OF": "não é um de" + }, + "toast": { + "created": "Fluxo criado", + "saved": "Fluxo salvo", + "saveError": "Falha ao salvar o fluxo", + "deleted": "Fluxo excluído", + "deleteError": "Falha ao excluir o fluxo", + "activateError": "Falha ao mudar o estado do fluxo" + }, + "editor": { + "createTitle": "Novo fluxo", + "visualTab": "Visual", + "codeTab": "Código", + "name": "Nome", + "description": "Descrição", + "conditions": "Condições", + "conditionsHint": "O fluxo roda quando um alerta cumpre TODAS estas condições.", + "field": "campo", + "value": "valor", + "valueList": "valores separados por vírgula", + "addCondition": "Adicionar condição", + "commands": "Comandos", + "commandsHint": "Executam em ordem no agente. Use $(field.path) para valores do alerta e $[variables.NAME] para variáveis salvas.", + "addCommand": "Adicionar comando", + "templatesButton": "Comandos comuns", + "templates": { + "isolate": "Isolar da rede", + "shutdown": "Desligar máquina", + "killProcess": "Matar processo", + "logout": "Encerrar sessão", + "disableUser": "Desativar usuário", + "blockIp": "Bloquear IP", + "restart": "Reiniciar a máquina", + "uninstall": "Desinstalar aplicação" + }, + "connector": { + "always": "sempre", + "success": "em caso de sucesso", + "failure": "em caso de falha" + }, + "agentPlatform": "Plataforma do agente", + "shell": "Shell", + "shellAuto": "auto", + "whereToRun": "Onde executar", + "run": { + "all": "Todos os agentes", + "specific": "Um agente", + "except": "Todos exceto", + "allHint": "Executa em todos os agentes que correspondem a esta plataforma." + }, + "selectAgentPlaceholder": "Selecione um agente…", + "excludedAgentsHint": "digite um hostname e pressione Enter", + "save": "Salvar", + "delete": "Excluir", + "confirmDelete": "Confirmar exclusão", + "cancel": "Cancelar", + "yamlError": "Não foi possível aplicar o YAML: {{error}}", + "nameRequired": "O nome é obrigatório", + "conditionsRequired": "É necessária ao menos uma condição com campo", + "commandsRequired": "É necessário ao menos um comando", + "httpUrlInvalid": "O nó HTTP \"{{id}}\" tem uma URL inválida — deve ser uma URL http(s) válida.", + "httpBodyInvalid": "O corpo do nó HTTP \"{{id}}\" não é JSON válido: {{error}}", + "incidentNameRequired": "O nó de incidente \"{{id}}\" precisa de um nome.", + "mailToRequired": "O nó de e-mail \"{{id}}\" precisa de ao menos um destinatário.", + "mailAddressInvalid": "O nó de e-mail \"{{id}}\" contém um endereço {{field}} inválido: {{address}}.", + "mailSubjectRequired": "O nó de e-mail \"{{id}}\" precisa de um assunto.", + "identityModalTitle": "Detalhes do fluxo", + "platformRequired": "A plataforma do agente é obrigatória", + "nameLabel": "Nome", + "namePlaceholder": "Nome do fluxo", + "descriptionLabel": "Descrição", + "descriptionHint": "O que este fluxo faz? (opcional)", + "when": "Quando", + "whenTitle": "Um alerta cumpre todas estas condições", + "on": "Em", + "onTitle": "O agente correspondente", + "thenRun": "Então execute", + "thenTitle": "Estes comandos, em ordem", + "selectField": "Escolher um campo…", + "selectPlatform": "Escolher uma plataforma…", + "searchAgents": "Buscar agentes…", + "noAgents": "Sem agentes", + "insertInto": "Inserir no comando {{n}}:", + "insertField": "Campo do alerta", + "variables": "Variáveis", + "canvas": { + "node": "Nó", + "deleteNode": "Excluir nó", + "id": "ID", + "kind": "Tipo", + "executor": "Executor", + "commandLabel": "Comando", + "paramsJson": "Parâmetros (JSON)", + "dragToResize": "Arraste para redimensionar", + "templatesLabel": "Modelos", + "templatesNeedPlatform": "Selecione primeiro a plataforma de destino", + "handlesHint": "Arraste do conector verde (inferior esquerdo) para on_success e do vermelho (inferior direito) para on_error. Várias conexões = paralelo. Várias conexões em um mesmo nó = AND-join.", + "invalidJson": "JSON inválido", + "hidePalette": "Ocultar paleta", + "hideInspector": "Ocultar inspetor", + "paletteLabel": "Paleta", + "nodeShort": "Nó", + "showPanel": "Mostrar {{name}}", + "platform": "Plataforma", + "shell": "Shell", + "any": "qualquer", + "auto": "auto", + "runOn": "Executar em", + "runAutoTitle": "Executa no host que gerou o alerta", + "runSpecificTitle": "Fixar em um host (ou um modelo como $(alert.foo))", + "runExceptTitle": "Executa no host que gerou o alerta, ignorando os da lista", + "runAutoLabel": "fonte do alerta", + "runSpecificLabel": "um host", + "runExceptLabel": "todos exceto", + "runAutoHint": "Executa em $(alert.dataSource) — o host que gerou o alerta.", + "pickHost": "escolha um host…", + "orTemplateHint": "Ou digite um modelo — $(alert.field) é resolvido por execução.", + "addExclusion": "adicionar exclusão", + "searchAgents": "buscar agentes…", + "noAgents": "sem agentes", + "insertField": "Inserir campo", + "alert": "Alerta", + "wholeOutput": "saída completa (edite o caminho)", + "noAncestorsHint": "Ainda não há ancestrais de enriquecimento — adicione um nó de enriquecimento acima para expor sua saída aqui.", + "inserts": "insere", + "conditionalHint": "Todas as condições devem corresponder. Correspondência → ramo de sucesso (verde); falha → ramo de erro (vermelho).", + "http": { + "url": "URL", + "urlInvalid": "URL http(s) inválida.", + "method": "Método", + "body": "Corpo (JSON)", + "bodyInvalid": "JSON inválido", + "headers": "Cabeçalhos HTTP", + "params": "Parâmetros da consulta", + "key": "Chave", + "value": "Valor", + "addHeader": "Adicionar cabeçalho", + "addParam": "Adicionar parâmetro" + }, + "incident": { + "name": "Nome do incidente", + "namePlaceholder": "Ex. Login suspeito em $(alert.dataSource)", + "description": "Descrição", + "descriptionPlaceholder": "Contexto opcional para respondentes. Modelos como $(alert.name) são interpolados." + }, + "llm": { + "prompt": "Prompt", + "hint": "O modelo é instruído a responder sempre com um único objeto JSON com a propriedade \"result\"; o backend garante esse formato mesmo se o modelo se desviar. Os nós filhos referenciam via $({{nodeId}}.result) ou campos específicos." + }, + "mail": { + "to": "Para (separados por vírgula)", + "cc": "CC (separados por vírgula, opcional)", + "addressInvalid": "Endereço de e-mail inválido: {{address}}", + "subject": "Assunto", + "subjectPlaceholder": "Ex. Alerta em $(alert.dataSource)", + "body": "Corpo", + "bodyPlaceholder": "Conteúdo da mensagem. Modelos como $(alert.name) são interpolados." + }, + "notify": { + "level": "Level", + "message": "Message", + "messagePlaceholder": "Notification text. Templates like $(alert.name) are interpolated." + } + } + }, + "executions": { + "search": "Buscar por ID de alerta…", + "all": "Todas", + "loading": "Carregando execuções…", + "loadError": "Não foi possível carregar as execuções.", + "retry": "Tentar de novo", + "empty": "Ainda não há execuções.", + "cols": { + "status": "Status", + "flow": "Fluxo", + "command": "Comando / Ação", + "agent": "Agente", + "date": "Data", + "retries": "Tentativas", + "node": "Nó" + }, + "filters": { + "source": "Origem", + "allSources": "Todas as origens" + }, + "manual": "Consola interativa" + }, + "executionStatus": { + "WAITING": "Aguardando", + "PENDING": "Pendente", + "EXECUTING": "Executando", + "EXECUTED": "Executado", + "FAILED": "Falhou", + "DEAD": "Inacessível" + }, + "executionOrigin": { + "FLOW": "Fluxo", + "MANUAL": "Manual" + }, + "nonExecutionCause": { + "AGENT_OFFLINE": "Agente offline", + "AGENT_NOT_FOUND": "Agente não encontrado", + "UNKNOWN": "Desconhecido" + }, + "kpi": { + "flows": "Fluxos totais", + "active": "Ativos", + "runs24h": "Execuções (24h)", + "failed24h": "Falhas (24h)" + }, + "neverRun": "nunca", + "create": { + "title": "Novo fluxo", + "modeManual": "Criar manualmente", + "modeAi": "Com IA", + "aiLocked": "Ative o SOC-AI e configure-o para usar isto.", + "name": "Nome do fluxo", + "namePlaceholder": "ex.: Bloquear IP em falhas repetidas", + "aiDescriptionLabel": "O que este fluxo deve fazer?", + "aiDescriptionPlaceholder": "ex.: Em um alerta crítico, pesquisar o IP de origem na inteligência de ameaças e bloqueá-lo no firewall", + "aiCreate": "Criar com IA", + "manualContinue": "Continuar" + } }, - "drawer": { - "loading": "Carregando…", - "loadFailed": "Não foi possível carregar a fonte de dados.", - "statsIdentity": "Stats e identidade", - "metadata": "Metadata", - "labelsSection": "Labels", - "dangerZone": "Zona de perigo", - "rows": { - "events24h": "Eventos 24h", - "lastSeen": "Visto por último", - "discovered": "Descoberta", - "kind": "Tipo de origem", - "dataType": "Tipo de dado", - "ip": "IP", - "id": "ID" - }, - "dangerText": "Excluir remove esta fonte do registro. Os eventos históricos continuam pesquisáveis no Log Explorer; se a fonte continuar enviando dados, será redescoberta.", - "delete": "Excluir fonte", - "confirmDelete": "Confirmar exclusão", - "cancel": "Cancelar", - "viewLogs": "Ver logs", - "trend": "Tendência de ingestão", - "noTrend": "Nenhum evento recebido nesta janela", - "logGap": "Último evento {{since}} — possível interrupção de logs" + "compliance": { + "title": "Compliance", + "subtitle": "Avalie sua postura frente a frameworks de segurança — veja quais controles são atendidos e quais não.", + "comingSoon": "Em breve.", + "tabs": { + "frameworks": "Frameworks", + "schedule": "Agendamento", + "controls": "Controles" + }, + "search": "Buscar frameworks…", + "refresh": "Refresh", + "loading": "Carregando frameworks…", + "loadError": "Could not load reports", + "retry": "Tentar de novo", + "empty": "Nenhum framework corresponde.", + "notEvaluated": "Não avaliado", + "controlsCount": "{{n}} controles", + "enabledLabel": "Ativo", + "runReport": "Executar relatório", + "backToFrameworks": "Voltar aos frameworks", + "statusAuto": "Auto (avaliado)", + "overrideError": "Falha ao atualizar o status", + "noteError": "Não foi possível salvar a nota", + "notes": { + "title": "Notas", + "placeholder": "Adicionar uma nota…", + "save": "Salvar", + "cancel": "Cancelar" + }, + "reasonModal": { + "title": "Motivo obrigatório", + "description": "Informe o motivo da alteração de status. Ele será registrado.", + "label": "Motivo", + "placeholder": "Explique por que está alterando o status deste controle…", + "confirm": "Confirmar alteração", + "cancel": "Cancelar" + }, + "coverageLabel": "Cobertura", + "activityLabel": "Atividade", + "evidenceLabel": "Evidência", + "seeMore": "Ver mais", + "seeLess": "Ver menos", + "evaluating": "Avaliando framework…", + "complianceScore": "Pontuação de compliance", + "generatedAt": "Gerado {{date}}", + "reportError": "Não foi possível gerar o relatório.", + "coverage": "{{n}} regras", + "activity": "{{n}} alertas", + "status": { + "COMPLIANT": "Conforme", + "NON_COMPLIANT": "Não conforme", + "AT_RISK": "Em risco", + "NOT_COVERED": "Sem cobertura", + "OUT_OF_SCOPE": "Fora do escopo", + "PENDING": "Pendente", + "label": "Status", + "NOT_EVALUATED": "Not evaluated" + }, + "toast": { + "toggleError": "Falha ao mudar o estado do framework", + "reportGenerated": "Relatório gerado", + "reportError": "Falha ao gerar o relatório" + }, + "schedule": { + "new": "Novo agendamento", + "loading": "Carregando agendamentos…", + "loadError": "Não foi possível carregar os agendamentos.", + "empty": "Ainda não há agendamentos.", + "edit": "Editar", + "delete": "Excluir", + "newTitle": "Novo agendamento", + "editTitle": "Editar agendamento", + "framework": "Framework", + "cadenceLabel": "Cadência", + "cronHint": "Cron de 5 campos (min hora dia mês diaSemana).", + "recipientsHint": "Emails separados por vírgula. Vazio = só armazena o snapshot.", + "save": "Salvar", + "cancel": "Cancelar", + "frameworkRequired": "O framework é obrigatório", + "cronRequired": "O agendamento (cron) é obrigatório", + "cadence": { + "daily": "Diário", + "weekly": "Semanal", + "monthly": "Mensal", + "custom": "Personalizado" + }, + "toast": { + "saved": "Agendamento salvo", + "saveError": "Falha ao salvar o agendamento", + "deleted": "Agendamento excluído", + "deleteError": "Falha ao excluir o agendamento" + }, + "to": "To", + "cc": "Cc", + "toRequired": "At least one recipient is required", + "windowDays": "Reporting window (days)", + "windowDaysShort": "over {{days}}d", + "windowDaysHint": "How far back the report counts. Independent of how often it runs." + }, + "frameworks": { + "new": "Novo framework", + "edit": "Editar", + "createTitle": "Novo framework", + "visualTab": "Visual", + "codeTab": "Código", + "key": "Chave", + "name": "Nome", + "description": "Descrição", + "source": "Fonte", + "sections": "Seções", + "sectionKey": "chave da seção", + "sectionName": "Nome da seção", + "requirements": "Requisitos", + "reqId": "id req", + "reqName": "Nome do requisito", + "addSection": "Adicionar seção", + "addRequirement": "Adicionar requisito", + "satisfiedBy": "satisfeito por controles", + "searchControls": "Buscar controles…", + "noControls": "Sem controles", + "save": "Salvar", + "delete": "Excluir", + "confirmDelete": "Confirmar exclusão", + "cancel": "Cancelar", + "yamlError": "Não foi possível aplicar o YAML: {{error}}", + "keyRequired": "A chave é obrigatória", + "nameRequired": "O nome é obrigatório", + "toast": { + "created": "Framework criado", + "saved": "Framework salvo", + "saveError": "Falha ao salvar o framework", + "deleted": "Framework excluído", + "deleteError": "Falha ao excluir o framework" + }, + "createControl": "Criar novo controle…", + "createNamed": "Criar controle \"{{name}}\"…" + }, + "controls": { + "search": "Buscar controles…", + "allFamilies": "Todas as famílias", + "new": "Novo controle", + "loading": "Carregando controles…", + "loadError": "Não foi possível carregar os controles.", + "empty": "Nenhum controle corresponde.", + "showingOf": "Mostrando {{shown}} de {{total}}", + "id": "ID", + "name": "Nome", + "family": "Família", + "familyName": "Família", + "scope": "Escopo", + "source": "Fonte", + "notInLibrary": "Controle não encontrado na biblioteca", + "scopeOpt": { + "data": "Dados", + "governance": "Governança" + }, + "strategy": "Estratégia", + "statement": "Enunciado", + "remediation": "Remediação", + "checks": "Checks", + "checksHint": "Cada check executa uma consulta SQL no OpenSearch e aplica uma regra para decidir passa/falha.", + "checkKey": "chave", + "checkName": "Nome do check", + "rule": { + "MIN_HITS_REQUIRED": "Mín hits exigidos", + "THRESHOLD_MAX": "Limite máx" + }, + "ruleNone": "Sem regra", + "ruleValue": "valor", + "addCheck": "Adicionar check", + "createTitle": "Novo controle", + "visualTab": "Visual", + "codeTab": "Código", + "save": "Salvar", + "delete": "Excluir", + "confirmDelete": "Confirmar exclusão", + "cancel": "Cancelar", + "yamlError": "Não foi possível aplicar o YAML: {{error}}", + "idRequired": "O ID é obrigatório", + "nameRequired": "O nome é obrigatório", + "anyDataType": "Any data type", + "addFilter": "Add filter", + "filterField": "log.eventCode", + "filterValue": "value", + "filterValues": "a, b, c", + "toast": { + "created": "Controle criado", + "saved": "Controle salvo", + "saveError": "Falha ao salvar o controle", + "deleted": "Controle excluído", + "deleteError": "Falha ao excluir o controle" + } + }, + "doc": { + "title": "Relatório de Compliance", + "print": "Imprimir / PDF", + "controlsEvaluated": "{{n}} controles avaliados", + "executiveSummary": "Resumo Executivo", + "bySection": "Achados por Seção", + "footer": "{{framework}} — Relatório de compliance gerado {{date}} · {{brand}}", + "download": "Baixar PDF", + "downloadError": "Falha ao baixar o PDF", + "error": "Não foi possível gerar o PDF", + "building": "Gerando o documento…" + }, + "locked": { + "badge": "Enterprise", + "upgrade": "Atualizar para Enterprise", + "upsell": "Este framework/controle requer a edição Enterprise." + }, + "run": "Run evaluation", + "runError": "Evaluation failed", + "noReportYet": "This framework has not been evaluated yet.", + "window": "window {{from}} → {{to}}", + "scoredOver": "{{compliant}} of {{evaluated}} requirements met · {{total}} in the framework", + "editStale": "Recorded when the engine said {{was}}; it now says {{now}}", + "checkResults": "Check results", + "verdict": "Recorded verdict", + "engineSaid": "engine said", + "hits": "hits", + "noDataFor": "no {{dataType}} data in the window", + "setStatus": "Set status", + "outcome": { + "PASSED": "Passed", + "FAILED": "Failed", + "NOT_APPLICABLE": "No data", + "ERROR": "Error" + }, + "system": "Do sistema", + "addNote": "Adicionar nota", + "noteModal": { + "title": "Nota", + "description": "Registrada no relatório. Não altera o estado do controle.", + "placeholder": "Remediação em curso — ticket OPS-4412." + }, + "history": { + "title": "Score ao longo do tempo", + "score": "Score de conformidade", + "coverage": "Avaliados", + "error": "Não foi possível carregar o histórico" + } }, - "toast": { - "labelsUpdated": "Labels atualizados", - "labelsFailed": "Falha ao atualizar os labels", - "deleted": "Fonte excluída", - "deleteFailed": "Falha ao excluir" + "taggingRules": { + "title": "Regras de Marcação", + "subtitle": "Marque automaticamente alertas que correspondam às condições.", + "new": "Nova regra", + "refresh": "Atualizar", + "empty": "Ainda não há regras de marcação.", + "loadError": "Não foi possível carregar as regras de marcação.", + "retry": "Tentar novamente", + "deleteConfirm": "Excluir a regra \"{{name}}\"? Os próximos alertas que corresponderem às suas condições deixarão de ser marcados.", + "toolbar": { + "search": "Buscar pelo nome da regra…", + "allTags": "Todas as etiquetas" + }, + "table": { + "rule": "Regra", + "tags": "Etiquetas", + "conditions": "Condições", + "modifiedBy": "Modificado por", + "modifiedDate": "Modificado" + }, + "drawer": { + "createTitle": "Nova regra de marcação", + "edit": "Editar", + "delete": "Excluir", + "save": "Salvar", + "create": "Criar", + "cancel": "Cancelar" + }, + "form": { + "basics": "Informações básicas", + "name": "Nome da regra", + "namePlaceholder": "ex.: Força bruta SSH interno", + "description": "Descrição", + "descriptionPlaceholder": "Por que esta regra existe e o que ela marca.", + "tags": "Etiquetas a aplicar", + "noTags": "Nenhuma etiqueta selecionada.", + "addTag": "Adicionar etiqueta", + "removeTag": "Remover", + "noCatalog": "Ainda não há etiquetas no catálogo.", + "createTag": "Criar etiqueta", + "newTagName": "Nome da nova etiqueta", + "conditions": "Condições (TODAS devem corresponder)", + "noConditions": "É necessária pelo menos uma condição.", + "addCondition": "Adicionar condição", + "removeCondition": "Remover condição", + "valuePlaceholder": "Valor", + "valueListPlaceholder": "Valores separados por vírgula", + "incomplete": "Preencha o nome da regra, a descrição, ao menos uma etiqueta e complete todas as condições." + }, + "view": { + "description": "Descrição", + "tags": "Etiquetas", + "conditions": "Condições", + "audit": "Auditoria", + "createdBy": "Criado por", + "createdDate": "Criado", + "modifiedBy": "Modificado por", + "modifiedDate": "Modificado" + }, + "toast": { + "created": "Regra \"{{name}}\" criada.", + "updated": "Regra \"{{name}}\" atualizada.", + "deleted": "Regra \"{{name}}\" excluída.", + "createError": "Falha ao criar a regra.", + "updateError": "Falha ao atualizar a regra.", + "deleteError": "Falha ao excluir a regra." + }, + "deleteTitle": "Excluir regra de marcação" + }, + "threatIntel": { + "header": { + "matchedInEnv": "coincidências em seu ambiente", + "export": "Exportar IOCs", + "exporting": "Exportando…", + "noInstanceIocs": "Sem indicadores de instância — exibindo dados genéricos", + "noInstanceIocsHint": "Nenhum indicador observado em seus alertas — exibindo dados genéricos dos feeds." + }, + "overview": { + "title": "Correspondências de IOC", + "totalIndicators": "indicadores totais", + "families": { + "ip": "IP", + "url": "URL", + "domain": "Domínio", + "signatures": "Assinaturas" + } + }, + "notConfigured": { + "title": "Threat Intelligence não está configurado", + "body": "Entre em contato com seu administrador para conectar uma instância do Cyber Mantra / ThreatWinds a este ambiente." + }, + "lookup": { + "title": "Pesquisar qualquer indicador", + "placeholder": "Cole um IP, domínio, hash, URL ou CVE — verificaremos os feeds e seu ambiente", + "button": "Pesquisar", + "busy": "Pesquisando…" + }, + "tabs": { + "iocs": "IOCs", + "actors": "Atores de ameaça", + "feeds": "Feeds", + "analyst": "Analista de IA" + }, + "toolbar": { + "searchPlaceholders": { + "iocs": "Pesquise valor IOC, tag, fonte…", + "actors": "Pesquise atores, aliases, técnicas…", + "feeds": "Pesquise feeds…" + }, + "last24h": "Últimas 24 horas", + "filters": "Filtros", + "refresh": "Atualizar" + }, + "iocs": { + "table": { + "type": "Tipo", + "indicator": "Indicador", + "reputation": "Reputação", + "tags": "Tags", + "lastSeen": "Visto pela última vez" + }, + "empty": "Nenhuma correspondência de IOC.", + "loadingMore": "Carregando mais…", + "loadedProgress": "Carregados {{loaded}} de {{total}}. Role para mais.", + "endOfResults": "Fim dos resultados ({{loaded}} de {{total}})." + }, + "drawer": { + "loading": "Carregando…", + "accuracy": "Precisão:", + "actions": { + "block": "Bloquear no perímetro", + "viewEvents": "Ver eventos correspondentes", + "externalLookup": "Pesquisa externa", + "trackCampaign": "Rastrear campanha", + "viewIocs": "Ver IOCs correspondentes", + "mitre": "MITRE ATT&CK" + }, + "sections": { + "timeline": "Linha do tempo", + "networkOrigin": "Rede / origem", + "associationsWithCount": "Associações ({{count}})", + "geolocationsWithCount": "Geolocalizações ({{count}})", + "about": "Sobre", + "activity": "Atividade" + }, + "fields": { + "firstSeen": "Visto pela primeira vez", + "lastSeen": "Visto pela última vez", + "country": "País", + "city": "Cidade", + "aso": "ASO", + "asn": "ASN", + "reputation": "Reputação", + "accuracy": "Precisão", + "current": "Atual", + "best": "Melhor", + "worst": "Pior" + }, + "aiBrief": "Resumo de IA", + "noDescription": "Nenhuma descrição disponível para este indicador.", + "lastObserved": "Última observação {{when}}." + }, + "actors": { + "empty": "Nenhum ator encontrado." + }, + "feeds": { + "empty": "Nenhum feed configurado.", + "table": { + "name": "Feed", + "type": "Tipo", + "accuracy": "Precisão", + "header": "Feeds", + "format": "Formato" + }, + "download": "Baixar feed", + "checksum": "Verificação" + }, + "entityTypes": { + "ip": "IP", + "hostname": "Host", + "domain": "Domínio", + "url": "URL", + "hash": "Hash", + "cve": "CVE", + "threat": "Ameaça", + "entity": "Entidade" + }, + "reputation": { + "alarming": "Alarmante", + "suspicious": "Suspeito", + "indefinable": "Indefinível", + "fair": "Justo", + "trustworthy": "Confiável" + }, + "feedAccuracy": { + "level1": "Nível 1", + "level2": "Nível 2", + "level3": "Nível 3" + }, + "triage": { + "title": "Triage", + "subtitle": "Paste indicators, get verdicts", + "input": "Indicators", + "placeholder": "Paste IPs, domains, URLs or hashes — one per line, or comma separated.\nDefanged values (1.2.3[.]4, hxxp://) are accepted.", + "run": "Triage", + "stop": "Stop", + "reset": "Clear", + "parsed": "{{count}} unique indicators", + "capped": "Capped at {{max}} per run.", + "progress": "{{done}} of {{total}}", + "empty": "Paste indicators above to begin.", + "indicator": "Indicator", + "type": "Type", + "verdict": "Verdict", + "reputation": "Rep", + "accuracy": "Acc", + "tags": "Tags", + "lastSeen": "Last seen", + "exportCsv": "Export CSV", + "exportStix": "Export STIX", + "stixNote": "STIX export includes malicious and suspicious rows only.", + "open": "Open", + "notConfigured": "Threat intelligence is not configured — triage needs an upstream ThreatWinds instance.", + "summary": "Summary", + "v.malicious": "Malicious", + "v.suspicious": "Suspicious", + "v.benign": "Benign", + "v.unknown": "Unknown", + "v.notFound": "Not found", + "v.invalid": "Unrecognised" + }, + "report": { + "title": "Reportar", + "subtitle": "Publicar um indicador no grafo ThreatWinds", + "submit": "Reportar indicador", + "submitting": "Reportando…", + "error": { + "generic": "Não foi possível enviar o indicador. Tente novamente." + }, + "value": { + "label": "Indicador", + "placeholder": "IP, domínio, URL, hash ou e-mail" + }, + "type": { + "label": "Tipo", + "placeholder": "Inferido do valor", + "inferred": "Inferido: {{type}}", + "inferenceFailed": "Nenhum tipo pôde ser inferido deste valor. Escolha um da lista ou digite.", + "unknown": "“{{type}}” não é um tipo de entidade. Escolha um da lista." + }, + "tags": { + "label": "Etiquetas", + "placeholder": "phishing, roubo-de-credenciais" + }, + "description": { + "label": "Notas" + }, + "reputation": { + "legend": "Reputação", + "hint": "Deixe em branco se você não chegou a um veredito.", + "alarming": "Alarmante", + "worrying": "Preocupante", + "concerning": "Suspeito", + "indefinable": "Indefinível", + "adequate": "Adequado", + "good": "Bom", + "exceptional": "Excelente" + }, + "associations": { + "legend": "Indicadores relacionados", + "add": "Adicionar indicador relacionado", + "remove": "Remover", + "valuePlaceholder": "Valor relacionado", + "typePlaceholder": "Tipo (opcional)", + "modeLabel": "Relação", + "mode": { + "association": "Relacionado a", + "aggregation": "Parte de" + }, + "visibilityConflict": "Não compartilha nenhum grupo de visibilidade com o indicador acima. Todo o envio seria rejeitado." + }, + "attributes": { + "legend": "Detalhes", + "hint": "Opcional. Qualquer campo em branco não é enviado.", + "invalidHex": "Esperados {{length}} caracteres hexadecimais.", + "invalidHexAny": "Apenas caracteres hexadecimais.", + "invalidNumber": "Esperado um número." + }, + "correlate": { + "legend": "Correlacionar", + "hint": "Cada atributo marcado é publicado como entidade própria, vinculada a esta.", + "count_one": "Cria {{count}} entidade vinculada.", + "count_other": "Cria {{count}} entidades vinculadas." + }, + "scan": { + "notice": "Reportar isto também enfileira uma varredura do alvo." + }, + "receipt": { + "title": "Enviado", + "noVerdict": "Sem veredito", + "skipped": "Não enviado, nenhum tipo pôde ser inferido", + "pending": "Aguardando o indicador aparecer no corpus…", + "live": "No ar no corpus — ver entidade", + "processing": "Ainda em processamento. Aparecerá quando a ingestão estiver em dia.", + "another": "Reportar outro" + }, + "visibility": { + "legend": "Visível para" + }, + "example": "Tentar um exemplo" + } }, - "console": { - "section": "Console", - "sectionHint": "Execute comandos neste host através do seu agente (resposta ao vivo).", - "open": "Abrir console", - "close": "Fechar", - "hint": "Digite um comando e pressione Enter para executá-lo no agente.", - "running": "Executando…", - "placeholder": "Digite um comando…", - "offline": "Este agente parece estar offline — pode não responder aos comandos.", - "vars": { - "button": "Variáveis", - "title": "Variáveis de comandos", - "subtitle": "Use-as nos comandos como", - "add": "Nova variável", - "name": "Nome", - "value": "Valor", - "description": "Descrição", - "isSecret": "Secreto (criptografado, mascarado na saída)", - "secret": "secreto", - "secretHint": "Deixe em branco para manter o valor salvo.", - "save": "Salvar", - "cancel": "Cancelar", - "edit": "Editar", - "delete": "Excluir", - "loading": "Carregando…", - "empty": "Ainda não há variáveis.", - "saved": "Variável salva", - "deleted": "Variável excluída", - "nameRequired": "O nome é obrigatório", - "loadError": "Falha ao carregar as variáveis", - "saveError": "Falha ao salvar a variável", - "deleteError": "Falha ao excluir a variável", - "insert": "Inserir", - "valueRequired": "O valor é obrigatório" - }, - "disabled": "Agente offline — os comandos estão desabilitados", - "connError": "Erro de conexão", - "cmdError": "Erro de comando", - "shellSelect": "Tipo de shell", - "noRemoteControl": "Este agente foi instalado com o controlo remoto desativado. Recusa comandos, e isso só pode ser alterado na própria máquina.", - "noRemoteControlShort": "Controlo remoto desativado neste agente", - "password": { - "title": "Autenticação", - "hint": "Autentique-se para executar comandos neste agente.", - "tfaPrompt": "Código: ", - "confirm": "OK", + "playground": { + "titleFilter": "Testar pipeline", + "titleRule": "Testar regra", + "noDataTypes": "Este pipeline ainda não tem tipos de dados atribuídos — adicione um para testá-lo.", + "dataTypeLabel": "Tipo de dado", + "dataTypePlaceholder": "Nenhum tipo de dado disponível", + "dataTypeSingleHint": "Este pipeline só tem um tipo de dado — adicione mais para poder escolher.", + "rawLogLabel": "Log bruto", + "rawLogPlaceholder": "Cole uma linha de log de exemplo…", + "rawLogCounter": "{{chars}} caracteres · {{kb}} KB", + "rawLogTooLarge": "Este log excede o limite de 1 MB — reduza-o antes de executar o teste.", + "run": { + "label": "Executar", + "running": "Testando…", + "waitHint": "Isso pode levar até 15 segundos enquanto o pipeline processa o log." + }, + "errors": { + "busy": "O playground está ocupado com outro teste — tente novamente em instantes.", + "timeout": "O teste expirou — normalmente significa que o tipo de dado selecionado não corresponde ao formato do log.", + "validation": "A requisição foi inválida — verifique o log bruto e o conteúdo do pipeline.", + "server": "O playground não conseguiu concluir o teste — tente novamente." + }, + "notices": { + "geo": "O plugin de geolocalização não está disponível nesta versão lite do teste de filtros e regras.", + "correlation": "As regras que referenciam eventos anteriores por meio das cláusulas afterEvent ou correlation exigem que eventos correspondentes já existam no sistema para que o alerta em teste seja disparado." + }, + "result": { + "label": "Resultado processado", + "empty": "Execute um teste para ver aqui o evento processado.", + "loading": "Aguardando o evento processado…", + "tabs": { + "fields": "Campos", + "json": "JSON" + }, + "fieldsCount_one": "{{count}} campo", + "fieldsCount_other": "{{count}} campos", + "copy": "Copiar", + "copied": "Copiado", + "elapsed": "Processado em {{time}}", + "elapsedHint": "Tempo entre Executar e o resultado processado", + "searchPlaceholder": "Buscar campos…", + "noMatch": "Nenhum campo corresponde à sua busca." + }, + "alerts": { + "label": "Alertas", + "empty": "Execute um teste para ver aqui os alertas gerados.", + "none": "Nenhum alerta foi disparado.", + "count_one": "{{count}} alerta", + "count_other": "{{count}} alertas" + }, + "title": "Test pipeline" + }, + "tenants": { + "title": "Tenants", + "new": "Novo tenant", + "subtitle": "Cada cliente nesta instância, o que ele tem e o que deixa você ver.", + "searchPlaceholder": "Pesquisar por nome ou domínio…", + "loading": "Carregando tenants…", + "loadFailed": "Não foi possível carregar os tenants.", + "retry": "Tentar novamente", + "none": "Ainda não há tenants.", + "noSearchMatch": "Nenhum tenant corresponde à pesquisa.", "cancel": "Cancelar", - "authError": "Falha na autenticação", - "authHint": "Autentique-se para executar comandos neste agente.", - "authOk": "Autenticado." - } - }, - "sensitivity": { - "section": "Sensibilidade do ativo", - "hint": "Criticidade de negócio (CIA, 0–3) deste ativo. Alertas direcionados ao seu host/IP são ponderados por esses valores.", - "saved": "Sensibilidade atualizada", - "failed": "Falha ao atualizar a sensibilidade", - "save": "Salvar", - "confidentiality": "Confidencialidade", - "integrity": "Integridade", - "availability": "Disponibilidade", - "levels": { - "0": "Nenhuma", - "1": "Baixa", - "2": "Média", - "3": "Alta" - } - }, - "health": { - "online": "online", - "offline": "offline", - "total": "total" - } - }, - "adversaries": { - "title": "Visão de adversários", - "subtitle": "Cada IP, host ou usuário visto atacando seu ambiente, com suas técnicas e alvos.", - "countChip": "{{count}} adversários", - "refresh": "Atualizar", - "search": "Pesquisar por IP, host, usuário, país, ASO…", - "empty": "Nenhum adversário corresponde.", - "loadError": "Não foi possível carregar os adversários.", - "retry": "Tentar novamente", - "views": { - "all": "Todos", - "high": "Severidade alta", - "ip": "IPs", - "host": "Hosts", - "user": "Usuários" - }, - "threat": { - "critical": "Crítico", - "high": "Alto", - "medium": "Médio", - "low": "Baixo" - }, - "kind": { - "ip": "IP", - "host": "Host", - "user": "Usuário" - }, - "layout": { - "list": "Lista", - "cards": "Cartões" - }, - "overview": { - "title": "Atividade de adversários · últimas 24 horas", - "high": "severidade alta", - "countries": "países", - "alerts": "alertas", - "ago24": "há 24h", - "ago12": "há 12h", - "now": "agora" - }, - "col": { - "adversary": "Adversário", - "threat": "Ameaça", - "alerts": "Alertas", - "targets": "Alvos", - "lastSeen": "Visto por último", - "victims": "Vítimas" - }, - "card": { - "alerts": "Alertas", - "techniques": "Técnicas", - "targets": "Alvos" - }, - "tabs": { - "profile": "Perfil", - "techniques": "Técnicas", - "targets": "Alvos", - "alerts": "Alertas" - }, - "drawer": { - "activity": "Atividade em 24 horas", - "identification": "Identificação", - "kindLabel": "Tipo", - "identifier": "Identificador", - "firstSeen": "Visto pela primeira vez", - "lastSeen": "Visto por último", - "geolocation": "Geolocalização", - "country": "País", - "city": "Cidade", - "topTechniques": "Principais técnicas", - "noTechniques": "Nenhuma técnica registrada.", - "targets": "Alvos", - "noTargets": "Nenhum alvo registrado.", - "recentAlerts": "Alertas recentes", - "noAlerts": "Sem alertas.", - "echoes": "{{count}} repetições" - }, - "relative": { - "justNow": "agora mesmo", - "minutesAgo": "há {{count}}m", - "hoursAgo": "há {{count}}h", - "daysAgo": "há {{count}}d" - }, - "field": { - "ip": "IP", - "host": "Host", - "user": "Usuário", - "port": "Porta", - "domain": "Domínio", - "mac": "MAC", - "country": "País", - "city": "Cidade", - "asn": "ASN", - "aso": "ASO" - } - }, - "timeRange": { - "quick": "Intervalos rápidos", - "relative": "Relativo", - "absolute": "Absoluto", - "last": "Últimos", - "apply": "Aplicar", - "allTime": "Todo o tempo", - "from": "De", - "to": "Até", - "now": "agora", - "units": { - "minutes": "minutos", - "hours": "horas", - "days": "dias", - "weeks": "semanas", - "months": "meses" - }, - "presets": { - "15m": "Últimos 15 minutos", - "1h": "Última hora", - "6h": "Últimas 6 horas", - "24h": "Últimas 24 horas", - "7d": "Últimos 7 dias", - "30d": "Últimos 30 dias" - } - }, - "socAi": { - "title": "Configuração do SOC-AI", - "subtitle": "Configure o agente de IA que faz triagem de alertas e alimenta o assistente de operações.", - "section": { - "connection": "Modelo e conexão", - "auth": "Autenticação", - "behavior": "Comportamento da triagem", - "advanced": "Avançado" - }, - "usage": { - "title": "Uso", - "chat": "Conclusões de chat (hoje)", - "unavailable": "O uso ainda não está disponível.", - "resetsIn": "Reinicia em {{time}}" - }, - "provider": { - "label": "Provedor", - "hint": "Define o formato. Qualquer um além do Anthropic usa a API compatível com OpenAI." - }, - "model": { - "label": "Modelo", - "hint": "Identificador do modelo do provedor.", - "customOption": "Modelo personalizado…", - "customPlaceholder": "Digite um ID de modelo" - }, - "url": { - "label": "URL da API", - "hint": "Deixe vazio para usar o endpoint padrão do provedor." - }, - "apiKey": { - "label": "Chave de API", - "hint": "Credencial enviada ao provedor.", - "setHint": "Há uma chave salva. Deixe em branco para mantê-la." - }, - "authType": { - "label": "Tipo de autenticação", - "hint": "Como as credenciais são enviadas ao seu gateway.", - "options": { - "apiKey": "API Key", - "bearer": "Bearer", - "customHeaders": "Cabeçalhos personalizados", - "none": "Nenhuma" - } - }, - "authHeaderName": { - "label": "Nome do cabeçalho de auth", - "hint": "Cabeçalho que carrega a chave (ex.: api-key para Azure)." - }, - "authToken": { - "label": "Token Bearer", - "hint": "Credencial enviada ao provedor.", - "setHint": "Um token está salvo. Deixe em branco para mantê-lo." - }, - "customHeaders": { - "label": "Cabeçalhos personalizados", - "hint": "Cabeçalhos extras enviados em cada requisição. Os valores são criptografados; \"*****\" mantém o salvo.", - "keyPlaceholder": "Nome do cabeçalho", - "valuePlaceholder": "Valor", - "addRow": "Adicionar cabeçalho", - "remove": "Remover cabeçalho" - }, - "maxTokens": { - "label": "Máx. tokens", - "hint": "Tokens máximos por resposta do LLM." - }, - "maxToolIterations": { - "label": "Máx. iterações de tools", - "hint": "Limite do loop planejar → tool → observar do agente." - }, - "autoAnalyze": { - "label": "Analisar alertas automaticamente", - "hint": "Faz triagem dos alertas recebidos em tempo real." - }, - "allowIncidents": { - "label": "Permitir gerenciar incidentes", - "hint": "O agente de triagem pode criar ou atualizar incidentes quando decide que um alerta o justifica." - }, - "changeAlertStatus": { - "label": "Alterar status do alerta", - "hint": "Permite ao agente definir o status de um alerta na triagem." - }, - "automaticIncidentCreation": { - "label": "Criar incidentes", - "hint": "Permite ao agente abrir incidentes a partir de alertas triados." - }, - "allowedWriteTools": { - "label": "Tools de escrita permitidas", - "hint": "Um nome de tool MCP por linha que o agente pode usar (ex.: alerts.update_status). Notas são sempre permitidas." - }, - "save": "Salvar configuração", - "saving": "Verificando e salvando…", - "saved": "Configuração do SOC-AI salva", - "saveError": "Falha ao salvar a configuração", - "loadError": "Falha ao carregar a configuração", - "modelRequired": "O modelo é obrigatório", - "applyTags": { - "label": "Aplicar tags", - "hint": "Permite ao agente marcar alertas com tags durante a triagem." - }, - "note": { - "azure": "Cole o endpoint completo do seu deployment do Azure como URL; o modelo é o nome do deployment. A auth usa o cabeçalho api-key.", - "ollama": "Aponte a URL para o seu host do Ollama. Não é necessária API key para uma instância local.", - "custom": "Qualquer endpoint compatível com OpenAI. Defina a URL, a auth e os cabeçalhos extras que seu gateway precisar.", - "threatwinds": "Usa sua licença UTMStack automaticamente — não precisa de API key. Cobrado através da sua assinatura ThreatWinds." - }, - "chat": { - "title": "Assistente SOC", - "dashboardCreateTitle": "Criador de painéis", - "empty": "Pergunte o que quiser sobre seus alertas, detecções ou o console — posso investigar e agir no SIEM.", - "tryPrefix": "Tente", - "suggestion": "quantos alertas abertos há, agrupados por adversário?", - "placeholder": "Digite uma pergunta…", - "ask": "Perguntar", - "send": "Enviar", - "collapse": "Recolher", - "expand": "Expandir", - "clear": "Limpar conversa", - "close": "Fechar", - "copy": "Copiar", - "copied": "Copiado", - "errorGeneric": "Algo deu errado.", - "errorUnreachable": "Não foi possível contatar o assistente.", - "compacting": "Compactando contexto…", - "dashboardEditTitle": "Editor de painéis", - "editingDashboard": "Editando: {{name}}", - "soarEditTitle": "Editor de fluxos SOAR", - "soarCreateTitle": "Criar fluxo SOAR", - "editingFlow": "Editando fluxo: {{name}}" - }, - "focus": { - "alert": "Alerta", - "incident": "Incidente", - "remove": "Parar de compartilhar com o assistente" - }, - "inheritance": { - "inherited": "Seguindo o padrão da instância. Salvar aqui dá a este tenant a própria configuração.", - "own": "Este tenant tem a própria configuração.", - "revert": "Voltar ao padrão da instância", - "reverting": "Revertendo…", - "reverted": "Agora segue o padrão da instância" - }, - "allowance": { - "title": "Consumo de IA hoje", - "ofLimit": "de {{limit}} requisições", - "denied": "requisições — a IA não está disponível para este tenant", - "hint": "Definido por quem opera a instância. Reinicia à meia-noite UTC." - } - }, - "alerts": { - "title": "Alertas", - "matching": "{{count}} correspondentes", - "subtitle": "Priorize o que importa.", - "openNow": "abertos agora.", - "view": { - "alerts": "Alertas", - "overview": "Visão geral" - }, - "toolbar": { - "searchPlaceholder": "Buscar por nome do alerta…", - "allSeverities": "Todas as severidades", - "export": "Exportar CSV", - "refresh": "Atualizar" - }, - "severity": { - "high": "Alta", - "medium": "Média", - "low": "Baixa" - }, - "status": { - "open": "Aberto", - "in_review": "Em revisão", - "completed": "Concluído", - "auto": "Revisão automática" - }, - "statusTabs": { - "all": "Todos" - }, - "overview": { - "overTime": "Alertas ao longo do tempo", - "matchingAlerts": "alertas correspondentes", - "noData": "Sem dados.", - "bySeverity": "Por severidade", - "byStatus": "Por estado" - }, - "filters": { - "add": "Adicionar filtro", - "clearAll": "Limpar tudo", - "filterValues": "Filtrar valores…", - "loadingValues": "Carregando valores…", - "noValues": "Nenhum valor encontrado.", - "pickValue": "Escolha um valor para adicionar o filtro.", - "empty": "(vazio)", - "cancel": "Cancelar", - "addBtn": "Adicionar" - }, - "ops": { - "CONTAIN": "contém", - "IS": "é", - "IS_NOT": "não é", - "EXIST": "existe", - "DOES_NOT_EXIST": "não existe" - }, - "fields": { - "adversary_domain": "Domínio do adversário", - "adversary_geolocation_asn": "ASN do adversário", - "adversary_geolocation_aso": "ASO do adversário", - "adversary_geolocation_country": "País do adversário", - "adversary_host": "Host do adversário", - "adversary_ip": "IP do adversário", - "adversary_url": "URL do adversário", - "adversary_user": "Utilizador do adversário", - "assignee": "Atribuído a", - "category": "Categoria", - "dataSource": "Sensor", - "dataType": "Tipo de dado", - "description": "Descrição", - "id": "ID", - "impactScore": "Risco", - "impact_availability": "Disponibilidade", - "impact_confidentiality": "Confidencialidade", - "impact_integrity": "Integridade", - "incidentDetail_incidentName": "Nome do incidente", - "incidentDetail_incidentId": "Id do incidente", - "isIncident": "É incidente", - "name": "Nome do alerta", - "notes": "Notas", - "severity": "Severidade", - "status": "Estado", - "tags": "Etiquetas", - "target_domain": "Domínio do alvo", - "target_geolocation_asn": "ASN do alvo", - "target_geolocation_aso": "ASO do alvo", - "target_geolocation_country": "País do alvo", - "target_host": "Host do alvo", - "target_ip": "IP do alvo", - "target_url": "URL do alvo", - "target_user": "Utilizador do alvo", - "technique": "Técnica" - }, - "tagFilter": { - "tags": "Etiquetas", - "tag_one": "{{count}} etiqueta", - "tag_other": "{{count}} etiquetas", - "clearSelection": "Limpar seleção", - "noTags": "Sem etiquetas" - }, - "bulk": { - "selected": "{{count}} selecionados", - "setStatus": "Definir estado", - "addTag": "Adicionar etiqueta", - "noTags": "Sem etiquetas", - "addToIncident": "Adicionar a incidente", - "clear": "Limpar" - }, - "tagEditor": { - "tag": "Etiqueta", - "noTagsYet": "Ainda não há etiquetas", - "createTag": "Criar etiqueta", - "newTagName": "Nome da nova etiqueta…", - "createApply": "Criar e aplicar etiqueta", - "save": "Salvar", - "cancel": "Cancelar", - "edit": "Editar etiqueta", - "delete": "Excluir etiqueta", - "systemLocked": "Etiqueta do sistema (bloqueada)", - "alreadyExists": "Essa etiqueta já existe.", - "color": "Cor {{color}}", - "createRule": "Criar regra de marcação com esta etiqueta" - }, - "table": { - "actions": "Ações", - "alert": "Alerta", - "status": "Estado", - "technique": "Técnica", - "severity": "Severidade", - "risk": "Risco", - "echoes": "Ecos", - "time": "Hora", - "riskHint": "Pontuação de risco (0–100), colorida por severidade", - "source": "Origem", - "adversary": "Adversário" - }, - "row": { - "createRuleFromAlert": "Criar uma tag a partir deste alerta", - "createIncident": "Criar incidente a partir deste alerta", - "viewIncident": "Ver detalhes do incidente", - "assignedTo": "Atribuído a {{user}}", - "echoesTooltip": "{{count}} ecos — clique para expandir", - "echoesEmpty": "Sem ecos registrados" - }, - "echoes": { - "title": "{{count}} ecos", - "close": "Fechar", - "empty": "Nenhum eco registrado para este alerta.", - "loadError": "Não foi possível carregar os ecos." - }, - "list": { - "loading": "Carregando alertas…", - "loadError": "Não foi possível carregar os alertas.", - "retry": "Tentar novamente", - "empty": "Nenhum alerta corresponde a esta visão." - }, - "badge": { - "incident": "Incidente", - "aiAssessed": "Avaliado por IA" - }, - "drawer": { - "setStatus": "Definir estado", - "completeFalsePositive": "Concluir + falso positivo", - "addToIncident": "Adicionar a incidente", - "partOfIncident": "Parte de um incidente", - "tabs": { - "summary": "Resumo", - "parties": "Partes", - "events": "Eventos", - "history": "Histórico" - }, - "section": { - "description": "Descrição", - "solution": "Solução", - "references": "Referências", - "details": "Detalhes", - "yourNotes": "Suas notas", - "notes": "Notas" - }, - "details": { - "severity": "Severidade", - "risk": "Risco", - "category": "Categoria", - "technique": "Técnica", - "sensor": "Sensor", - "dataType": "Tipo de dado", - "alertId": "ID do alerta", - "statusNote": "Nota de estado", - "assignee": "Responsável" - }, - "incidentDetail": { - "incident": "Incidente", - "id": "ID", - "createdBy": "Criado por", - "created": "Criado" - }, - "notesPlaceholder": "Adicione notas de investigação…", - "saveNotes": "Salvar notas", - "assignee": "Atribuir", - "assign": "Atribuir", - "unassign": "Remover atribuição", - "unassigned": "Sem responsável", - "loadingUsers": "Carregando usuários…", - "observationLabel": "Observação", - "observationPlaceholder": "Adicionar uma observação…", - "cancel": "Cancelar", - "continue": "Continuar" - }, - "related": { - "sample": "Uma amostra de até ~11 eventos que o mecanismo armazenou neste alerta. Use «Ver todos os registros relacionados» para o conjunto completo e sem limite.", - "loadingEchoes": "Carregando os eventos dos seus ecos…", - "sampleWithEchoes": "Os eventos guardados neste alerta e nos seus {{count}} ecos ({{read}} lidos). Use «Ver todos os registros relacionados» para o conjunto completo e sem limite.", - "empty": "Nenhum evento de amostra armazenado neste alerta. Carregue o conjunto correlacionado completo no Explorador de registros.", - "viewAll": "Ver todos os registros relacionados" - }, - "party": { - "source": "Origem / alvo", - "adversary": "Adversário", - "noData": "Sem dados.", - "ip": "IP", - "host": "Host", - "user": "Usuário", - "domain": "Domínio", - "country": "País" - }, - "history": { - "empty": "Nenhum histórico registrado.", - "by": "por {{user}}", - "actions": { - "UPDATE_STATUS": "Estado atualizado", - "UPDATE_TAGS": "Etiquetas atualizadas", - "UPDATE_NOTES": "Notas atualizadas", - "UPDATE_SOLUTION": "Solução atualizada", - "MARK_AS_INCIDENT": "Marcado como incidente" - }, - "detail": { - "statusTo": "Estado → {{status}}", - "tags": "Etiquetas: {{tags}}", - "aiAdded": "Avaliação de IA adicionada", - "observationAdded": "Observação adicionada", - "notesUpdated": "Notas atualizadas" - } - }, - "ai": { - "title": "Avaliação de IA do SOC", - "risk": "risco {{risk}}", - "score": "{{score}}/100", - "generate": "Gerar resumo de IA", - "hint": "O SOC-AI investiga este alerta e adiciona uma avaliação.", - "generating": "Analisando o alerta… pode levar um minuto.", - "ready": "Resumo de IA pronto", - "failed": "Não foi possível gerar o resumo de IA", - "slow": "O resumo de IA está demorando mais que o esperado. Ele aparecerá no alerta quando estiver pronto." - }, - "incident": { - "titleAdd_one": "Adicionar {{count}} alerta a um incidente", - "titleAdd_other": "Adicionar {{count}} alertas a um incidente", - "new": "Novo incidente", - "existing": "Incidente existente", - "nameLabel": "Nome do incidente", - "namePlaceholder": "ex.: Suspeita de intrusão de Scattered Spider", - "descriptionLabel": "Descrição", - "descriptionPlaceholder": "Resumo opcional…", - "pickLabel": "Escolha um incidente", - "loading": "Carregando…", - "selectPlaceholder": "Selecione um incidente…", - "willLink_one": "{{count}} alerta será vinculado.", - "willLink_other": "{{count}} alertas serão vinculados.", - "cancel": "Cancelar", - "create": "Criar incidente", - "add": "Adicionar a incidente" - }, - "toast": { - "statusUpdated": "Estado atualizado", - "statusFailed": "Falha ao atualizar o estado", - "tagsUpdated": "Etiquetas atualizadas", - "tagsFailed": "Falha ao atualizar as etiquetas", - "tagCreateFailed": "Falha ao criar a etiqueta", - "tagUpdated": "Etiqueta atualizada", - "tagUpdateFailed": "Falha ao atualizar a etiqueta", - "tagDeleted": "Etiqueta excluída", - "tagDeleteFailed": "Falha ao excluir a etiqueta", - "notesSaved": "Notas salvas", - "notesFailed": "Falha ao salvar as notas", - "exportFailed": "Falha ao exportar o CSV", - "noRelatedLogs": "Nenhum registro relacionado encontrado para este alerta", - "relatedLogsFailed": "Falha ao carregar os registros relacionados", - "incidentCreated": "Incidente criado", - "alertsAdded": "Alertas adicionados ao incidente", - "incidentFailed": "Falha ao salvar o incidente", - "assigned": "Alerta atribuído", - "unassigned": "Alerta sem responsável", - "assignFailed": "Não foi possível atualizar o responsável", - "newAlertsToast_title": "Novas alertas", - "newAlertsToast_count_one": "{{count}} nova alerta", - "newAlertsToast_count_other": "{{count}} novas alertas", - "newAlertsToast_view": "Ver" - } - }, - "incidents": { - "title": "Incidentes", - "subtitle": "Agrupe, triagem e resolva alertas relacionados como incidentes.", - "refresh": "Atualizar", - "count_one": "{{count}} incidente", - "count_other": "{{count}} incidentes", - "openNow": "abertos agora", - "empty": "Nenhum incidente corresponde.", - "loadError": "Não foi possível carregar os incidentes.", - "retry": "Tentar novamente", - "unassigned": "Não atribuído", - "unknownUser": "Desconhecido", - "status": { - "open": "Aberto", - "in_review": "Em revisão", - "completed": "Concluído", - "merged": "Mesclado" - }, - "sev": { - "high": "Alta", - "medium": "Média", - "low": "Baixa", - "unknown": "Sem classificação" - }, - "toolbar": { - "search": "Buscar incidentes…", - "create": "Criar incidente", - "allSeverities": "Todas as severidades", - "export": "Exportar CSV" - }, - "statusTabs": { - "all": "Todos" - }, - "filters": { - "add": "Adicionar filtro", - "clearAll": "Limpar tudo", - "filterValues": "Filtrar valores…", - "loadingValues": "Carregando valores…", - "noValues": "Nenhum valor encontrado.", - "pickValue": "Escolha um valor para adicionar o filtro.", - "empty": "(vazio)", - "cancel": "Cancelar", - "addBtn": "Adicionar" - }, - "ops": { - "IS": "é" - }, - "layout": { - "table": "Tabela", - "board": "Quadro" - }, - "table": { - "name": "Incidente", - "status": "Status", - "severity": "Severidade", - "assignee": "Responsável", - "alerts": "Alertas", - "created": "Criado" - }, - "drawer": { - "created": "Criado {{date}}", - "alertsCount": "{{count}} alertas", - "solutionPlaceholder": "Resolução / notas de remediação…", - "solutionHint": "Salvo ao mover o incidente para Concluído.", - "tabs": { - "overview": "Resumo", - "alerts": "Alertas", - "notes": "Notas", - "history": "Histórico" - }, - "section": { - "description": "Descrição", - "solution": "Solução", - "details": "Detalhes" - }, - "details": { - "id": "ID", - "status": "Status", - "severity": "Severidade", - "assignee": "Responsável", - "created": "Criado", - "alerts": "Alertas vinculados" - } - }, - "alerts": { - "empty": "Nenhum alerta vinculado a este incidente.", - "remove": "Desvincular alerta", - "removeConfirm": "Desvincular “{{name}}” deste incidente?", - "removed": "Alerta desvinculado", - "removeError": "Não foi possível desvincular o alerta", - "loadingAlert": "A carregar alerta…", - "alertGone": "Este alerta já não está no armazenamento — a retenção pode tê-lo removido.", - "alertFailed": "Não foi possível carregar o alerta.", - "openInAlerts": "Abrir em Alertas" - }, - "notes": { - "empty": "Ainda sem notas.", - "add": "Adicionar nota", - "addError": "Não foi possível adicionar a nota", - "placeholder": "Escreva uma nota…" - }, - "history": { - "empty": "Ainda sem histórico." - }, - "toast": { - "statusChanged": "Status do incidente atualizado", - "statusError": "Não foi possível alterar o status", - "exportFailed": "Falha ao exportar o CSV" - }, - "assign": { - "assign": "Atribuir", - "search": "Buscar usuários…", - "unassign": "Remover atribuição", - "noUsers": "Sem usuários", - "assigned": "Atribuído a {{user}}", - "unassigned": "Incidente sem atribuição", - "error": "Não foi possível alterar o responsável", - "custom": "Atribuir personalizado", - "customPlaceholder": "Digite um login…" - }, - "action": { - "INCIDENT_CREATED": "Incidente criado", - "INCIDENT_ALERT_ADD": "Alertas adicionados", - "INCIDENT_ALERT_STATUS_CHANGED": "Estado dos alertas alterado", - "INCIDENT_STATUS_CHANGE": "Estado alterado", - "INCIDENT_NOTE_ADD": "Nota adicionada", - "INCIDENT_NOTE_CHANGE": "Nota editada", - "INCIDENT_ASSIGNED": "Atribuição alterada" - }, - "create": { - "title": "Criar incidente", - "stepIndicator": "Etapa {{current}} de {{total}}", - "selectedCount": "{{count}} alertas selecionados", - "submit": "Criar", - "success": "Incidente criado", - "error": "Não foi possível criar o incidente", - "details": { - "nameLabel": "Nome", - "namePlaceholder": "Título curto e descritivo", - "descriptionLabel": "Descrição", - "descriptionPlaceholder": "Contexto, escopo, notas iniciais…" - } - } - }, - "parsingFilters": { - "title": "Pipelines", - "subtitle": "Pipelines YAML aplicados aos logs enquanto são processados na ingestão.", - "new": "Novo pipeline", - "search": "Buscar pipelines…", - "refresh": "Atualizar", - "view": "Ver", - "system": "Sistema", - "user": "Personalizado", - "loading": "Carregando pipelines…", - "loadError": "Não foi possível carregar os pipelines.", - "retry": "Tentar novamente", - "empty": "Nenhum pipeline corresponde a esta vista.", - "tabs": { - "all": "Todos", - "active": "Ativos", - "inactive": "Inativos", - "system": "Sistema", - "user": "Personalizados" - }, - "cols": { - "filter": "Pipeline", - "type": "Tipo", - "active": "Ativo", - "dataTypes": "Tipos de dado", - "order": "Ordem", - "moveUp": "Mover para cima", - "moveDown": "Mover para baixo", - "actions": "Ações" - }, - "editor": { - "titleNew": "Novo pipeline", - "titleEdit": "Editar pipeline", - "titleSystem": "Pipeline (sistema)", - "name": "Nome", - "namePlaceholder": "Meu pipeline personalizado", - "nameHint": "Será salvo como {{file}}", - "namePending": "Escolha um nome — ele será o nome do arquivo.", - "content": "Conteúdo (pipeline YAML)", - "contentHint": "Uma definição válida em pipeline: YAML.", - "readOnly": "Pipeline do sistema — somente leitura. Você só pode ativá-lo ou desativá-lo.", - "save": "Salvar", - "saving": "Salvando…", - "delete": "Excluir", - "confirmDelete": "Confirmar exclusão", - "cancel": "Cancelar", - "test": "Test" - }, - "toast": { - "saved": "Pipeline salvo", - "saveError": "Falha ao salvar o pipeline", - "deleted": "Pipeline excluído", - "deleteError": "Falha ao excluir o pipeline", - "activateError": "Falha ao alterar o estado do pipeline", - "nameRequired": "O nome é obrigatório", - "contentRequired": "O conteúdo é obrigatório", - "orderError": "Falha ao reordenar o pipeline" - }, - "visual": { - "visualTab": "Visual", - "codeTab": "Código", - "codeOnly": "Mude para Código — este conteúdo não pode ser exibido visualmente.", - "cantParse": "Não foi possível abrir o editor visual: {{error}}", - "dataTypes": "Tipos de dado", - "steps": "Etapas", - "noSteps": "Ainda não há etapas.", - "addStep": "Adicionar etapa:", - "removeStep": "Remover etapa", - "moveUp": "Mover para cima", - "moveDown": "Mover para baixo", - "whereHint": "condição opcional (CEL)", - "addValue": "Adicionar valor", - "addPattern": "Adicionar padrão", - "rawHint": "Este processor é editado como YAML direto.", - "rawNotMap": "Deve ser um conjunto de campos chave: valor.", - "dataTypesPick": "Escolher tipos de dado", - "dataTypesSearch": "Buscar tipos de dado…", - "dataTypesNone": "Sem tipos de dado", - "dataTypesAdd": "Adicionar \"{{value}}\"", - "insertPattern": "Inserir padrão regex", - "patternSearch": "Buscar padrões…", - "patternNone": "Sem padrões", - "newPattern": "Novo padrão…", - "createInsert": "Criar e inserir", - "patternCreated": "Padrão \"{{name}}\" criado", - "patternCreateError": "Falha ao criar o padrão", - "patternIdInvalid": "O ID deve começar com letra ou _ e usar apenas letras, dígitos ou _", - "patternDefRequired": "A definição é obrigatória", - "parameters": "Parâmetros", - "paramsKey": "Chave", - "paramsValue": "Valor", - "entry": "Entrada {{n}}", - "order": "ordem {{n}}", - "orderLabel": "Ordem", - "removeEntry": "Remover entrada", - "addEntry": "Adicionar entrada de pipeline", - "collapse": "Recolher", - "expand": "Expandir", - "splitHint": "Vacío equivale a un espacio por defecto — en el YAML siempre aparece como fieldSplit: \" \"." - }, - "allDataTypes": "Todos os tipos de dado", - "testPipeline": "Test pipeline" - }, - "alertingRules": { - "title": "Regras de Alerta", - "subtitle": "Regras de correlação que transformam eventos em alertas. Ative, ajuste ou crie as suas.", - "new": "Nova regra", - "refresh": "Atualizar", - "empty": "Nenhuma regra corresponde.", - "loadError": "Não foi possível carregar as regras.", - "retry": "Tentar novamente", - "deleteConfirm": "Excluir a regra “{{name}}”?", - "adversary": { - "origin": "Origem", - "target": "Destino" - }, - "state": { - "active": "Ativa", - "inactive": "Inativa" - }, - "owner": { - "system": "Sistema", - "custom": "Personalizada" - }, - "toolbar": { - "search": "Buscar regras…", - "allCategories": "Todas as categorias", - "allAdversaries": "Todos os adversários", - "allStates": "Todos os estados", - "allOwners": "Todas as origens", - "allDataTypes": "Todos os tipos" - }, - "table": { - "name": "Regra", - "category": "Categoria", - "technique": "Técnica", - "adversary": "Adversário", - "impact": "Impacto", - "active": "Ativa", - "dataTypes": "Tipos de dado", - "selectAll": "Selecionar tudo", - "selectRow": "Selecionar {{name}}" - }, - "export": { - "all": "Exportar tudo", - "selected": "Exportar ({{count}})", - "error": "Não foi possível exportar as regras" - }, - "view": { - "description": "Descrição", - "details": "Detalhes", - "impact": "Impacto (C·I·D)", - "dataTypes": "Tipos de dado", - "updated": "Atualizada", - "relPath": "Caminho", - "definition": "Condição (CEL)", - "correlationSteps": "Passos de correlação", - "correlation": "Correlação", - "groupBy": "Agrupar por", - "deduplicateBy": "Deduplicar por", - "references": "Referências" - }, - "editor": { - "createTitle": "Nova regra", - "edit": "Editar", - "delete": "Excluir", - "export": "Exportar", - "cancel": "Cancelar", - "save": "Salvar", - "metadata": "Metadados", - "name": "Nome", - "confidentiality": "Confidencialidade", - "integrity": "Integridade", - "availability": "Disponibilidade", - "dataTypes": "Tipos de dado", - "dataTypesHint": "separados por vírgula", - "activeOnSave": "Ativa", - "definitionSection": "Definição", - "where": "Condição (CEL)", - "whereHint": "Expressão CEL avaliada por evento", - "correlationSteps": "Passos de correlação", - "correlationStepsHint": "array JSON", - "jsonArray": "array JSON", - "nameRequired": "O nome é obrigatório", - "definitionRequired": "A condição é obrigatória", - "invalidJson": "Um campo da definição tem JSON inválido", - "addStep": "Adicionar passo de correlação", - "step": "Passo {{n}}", - "removeStep": "Remover passo", - "indexPattern": "Padrão de índice", - "within": "Janela", - "count": "Quantidade", - "conditions": "Condições", - "field": "Campo", - "value": "Valor", - "addCondition": "Adicionar condição", - "orGroup": "Grupo Or {{n}}", - "addOr": "Adicionar grupo Or", - "removeOr": "Remover", - "fieldsHint": "nomes de campo", - "referencesHint": "URLs", - "visual": "Visual", - "code": "Código", - "dataTypesPick": "Selecionar…", - "dataTypesSearch": "Buscar tipos de dado…", - "dataTypesNone": "Sem tipos de dado", - "visualTab": "Visual", - "codeTab": "Código", - "yamlError": "Não foi possível aplicar o YAML: {{error}}", - "test": "Test" - }, - "toast": { - "activated": "Regra ativada", - "deactivated": "Regra desativada", - "toggleError": "Não foi possível alterar o estado da regra", - "deleted": "Regra excluída", - "deleteError": "Não foi possível excluir a regra", - "created": "Regra criada", - "saved": "Regra salva", - "saveError": "Não foi possível salvar a regra" - }, - "operator": { - "filter_term": "igual (term)", - "must_not_term": "diferente (term)", - "filter_match": "corresponde (texto)", - "must_not_match": "não corresponde (texto)" - }, - "where": { - "matchPrefix": "Corresponde a", - "all": "todas", - "any": "qualquer", - "matchSuffix": "destas condições:", - "negate": "Negar", - "listHint": "separado por vírgulas", - "advanced": "Esta condição usa CEL avançado — edite no Código ou reconstrua visualmente.", - "and": "E", - "or": "OU" - }, - "celOp": { - "exists": "existe", - "equals": "igual a", - "equalsIgnoreCase": "igual (sem maiús.)", - "contains": "contém", - "oneOf": "é um de", - "containsAll": "contém todos", - "startsWith": "começa com", - "endsWith": "termina com", - "regexMatch": "regex", - "lessThan": "<", - "lessOrEqual": "≤", - "greaterThan": ">", - "greaterOrEqual": "≥", - "inCIDR": "em CIDR", - "isHour": "a hora é", - "isMinute": "o minuto é", - "isDayOfWeek": "o dia é", - "isWeekend": "é fim de semana", - "isWorkDay": "é dia útil", - "isBetweenTime": "hora entre" - }, - "import": { - "button": "Importar", - "error": "Falha na importação", - "resultTitle": "Resultados da importação", - "approved": "Aprovadas", - "rejected": "Rejeitadas", - "done": "Concluído" - }, - "test": "Test" - }, - "regexPatterns": { - "title": "Expressões regulares", - "subtitle": "Expressões regulares reutilizáveis referenciadas pelos filtros de parsing.", - "new": "Novo padrão", - "search": "Buscar padrões…", - "refresh": "Atualizar", - "view": "Ver", - "system": "Sistema", - "user": "Personalizado", - "loading": "Carregando padrões…", - "loadError": "Não foi possível carregar os padrões.", - "retry": "Tentar novamente", - "empty": "Nenhum padrão corresponde a esta visão.", - "tabs": { - "all": "Todos", - "system": "Sistema", - "user": "Personalizados" - }, - "cols": { - "pattern": "Padrão", - "definition": "Definição", - "type": "Tipo" - }, - "editor": { - "titleNew": "Novo padrão", - "patternId": "ID do padrão", - "patternIdHint": "Nome único referenciado pelos filtros.", - "description": "Descrição", - "descriptionPlaceholder": "O que este padrão reconhece (opcional)", - "definition": "Definição (regex)", - "definitionHint": "Uma expressão regular. Pode referenciar outros padrões.", - "readOnly": "Padrão do sistema — somente leitura.", - "save": "Salvar", - "saving": "Salvando…", - "delete": "Excluir", - "confirmDelete": "Confirmar exclusão", - "cancel": "Cancelar" - }, - "toast": { - "saved": "Padrão salvo", - "saveError": "Falha ao salvar o padrão", - "deleted": "Padrão excluído", - "deleteError": "Falha ao excluir o padrão", - "patternIdRequired": "O ID do padrão é obrigatório", - "definitionRequired": "A definição é obrigatória" - } - }, - "soar": { - "title": "SOAR", - "subtitle": "Fluxos de resposta automática: as condições combinam um alerta e os comandos rodam no agente.", - "comingSoon": "Em breve", - "console": { - "loading": "Carregando agentes…", - "loadError": "Não foi possível carregar os agentes.", - "pickAgent": "Selecione um agente", - "pickAgentHint": "Escolha um agente da lista para abrir seu console interativo.", - "lockedAgent": "Controlo remoto desativado" - }, - "search": "Buscar fluxos…", - "refresh": "Atualizar", - "new": "Novo fluxo", - "view": "Ver", - "system": "Sistema", - "loading": "Carregando fluxos…", - "loadError": "Não foi possível carregar os fluxos.", - "retry": "Tentar de novo", - "empty": "Nenhum fluxo corresponde a esta visão.", - "templates": { - "title": "Novo fluxo", - "subtitle": "Escolha um modelo de ação ou comece do zero.", - "loading": "Carregando modelos…", - "loadError": "Não foi possível carregar os modelos.", - "empty": "Nenhum modelo disponível.", - "cancel": "Cancelar", - "scratch": "Começar do zero" - }, - "tabs": { - "flows": "Fluxos", - "executions": "Histórico de execuções", - "all": "Todos", - "active": "Ativos", - "inactive": "Inativos", - "system": "Sistema", - "user": "Próprios" - }, - "cols": { - "flow": "Fluxo", - "platform": "Plataforma", - "conditions": "Condições", - "commands": "Comandos", - "active": "Ativo", - "lastRun": "Última execução", - "failedRuns_one": "{{count}} execução falhada", - "failedRuns_other": "{{count}} execuções falhadas" - }, - "operator": { - "IS": "é", - "IS_NOT": "não é", - "CONTAINS": "contém", - "NOT_CONTAINS": "não contém", - "EXISTS": "existe", - "NOT_EXISTS": "não existe", - "START_WITH": "começa com", - "NOT_START_WITH": "não começa com", - "ENDS_WITH": "termina com", - "NOT_ENDS_WITH": "não termina com", - "IS_ONE_OF": "é um de", - "IS_NOT_ONE_OF": "não é um de" - }, - "toast": { - "created": "Fluxo criado", - "saved": "Fluxo salvo", - "saveError": "Falha ao salvar o fluxo", - "deleted": "Fluxo excluído", - "deleteError": "Falha ao excluir o fluxo", - "activateError": "Falha ao mudar o estado do fluxo" - }, - "editor": { - "createTitle": "Novo fluxo", - "visualTab": "Visual", - "codeTab": "Código", - "name": "Nome", - "description": "Descrição", - "conditions": "Condições", - "conditionsHint": "O fluxo roda quando um alerta cumpre TODAS estas condições.", - "field": "campo", - "value": "valor", - "valueList": "valores separados por vírgula", - "addCondition": "Adicionar condição", - "commands": "Comandos", - "commandsHint": "Executam em ordem no agente. Use $(field.path) para valores do alerta e $[variables.NAME] para variáveis salvas.", - "addCommand": "Adicionar comando", - "templatesButton": "Comandos comuns", - "templates": { - "isolate": "Isolar da rede", - "shutdown": "Desligar máquina", - "killProcess": "Matar processo", - "logout": "Encerrar sessão", - "disableUser": "Desativar usuário", - "blockIp": "Bloquear IP", - "restart": "Reiniciar a máquina", - "uninstall": "Desinstalar aplicação" - }, - "connector": { - "always": "sempre", - "success": "em caso de sucesso", - "failure": "em caso de falha" - }, - "agentPlatform": "Plataforma do agente", - "shell": "Shell", - "shellAuto": "auto", - "whereToRun": "Onde executar", - "run": { - "all": "Todos os agentes", - "specific": "Um agente", - "except": "Todos exceto", - "allHint": "Executa em todos os agentes que correspondem a esta plataforma." - }, - "selectAgentPlaceholder": "Selecione um agente…", - "excludedAgentsHint": "digite um hostname e pressione Enter", - "save": "Salvar", - "delete": "Excluir", - "confirmDelete": "Confirmar exclusão", - "cancel": "Cancelar", - "yamlError": "Não foi possível aplicar o YAML: {{error}}", - "nameRequired": "O nome é obrigatório", - "conditionsRequired": "É necessária ao menos uma condição com campo", - "commandsRequired": "É necessário ao menos um comando", - "httpUrlInvalid": "O nó HTTP \"{{id}}\" tem uma URL inválida — deve ser uma URL http(s) válida.", - "httpBodyInvalid": "O corpo do nó HTTP \"{{id}}\" não é JSON válido: {{error}}", - "incidentNameRequired": "O nó de incidente \"{{id}}\" precisa de um nome.", - "mailToRequired": "O nó de e-mail \"{{id}}\" precisa de ao menos um destinatário.", - "mailAddressInvalid": "O nó de e-mail \"{{id}}\" contém um endereço {{field}} inválido: {{address}}.", - "mailSubjectRequired": "O nó de e-mail \"{{id}}\" precisa de um assunto.", - "identityModalTitle": "Detalhes do fluxo", - "platformRequired": "A plataforma do agente é obrigatória", - "nameLabel": "Nome", - "namePlaceholder": "Nome do fluxo", - "descriptionLabel": "Descrição", - "descriptionHint": "O que este fluxo faz? (opcional)", - "when": "Quando", - "whenTitle": "Um alerta cumpre todas estas condições", - "on": "Em", - "onTitle": "O agente correspondente", - "thenRun": "Então execute", - "thenTitle": "Estes comandos, em ordem", - "selectField": "Escolher um campo…", - "selectPlatform": "Escolher uma plataforma…", - "searchAgents": "Buscar agentes…", - "noAgents": "Sem agentes", - "insertInto": "Inserir no comando {{n}}:", - "insertField": "Campo do alerta", - "variables": "Variáveis", - "canvas": { - "node": "Nó", - "deleteNode": "Excluir nó", - "id": "ID", - "kind": "Tipo", - "executor": "Executor", - "commandLabel": "Comando", - "paramsJson": "Parâmetros (JSON)", - "dragToResize": "Arraste para redimensionar", - "templatesLabel": "Modelos", - "templatesNeedPlatform": "Selecione primeiro a plataforma de destino", - "handlesHint": "Arraste do conector verde (inferior esquerdo) para on_success e do vermelho (inferior direito) para on_error. Várias conexões = paralelo. Várias conexões em um mesmo nó = AND-join.", - "invalidJson": "JSON inválido", - "hidePalette": "Ocultar paleta", - "hideInspector": "Ocultar inspetor", - "paletteLabel": "Paleta", - "nodeShort": "Nó", - "showPanel": "Mostrar {{name}}", - "platform": "Plataforma", - "shell": "Shell", - "any": "qualquer", - "auto": "auto", - "runOn": "Executar em", - "runAutoTitle": "Executa no host que gerou o alerta", - "runSpecificTitle": "Fixar em um host (ou um modelo como $(alert.foo))", - "runExceptTitle": "Executa no host que gerou o alerta, ignorando os da lista", - "runAutoLabel": "fonte do alerta", - "runSpecificLabel": "um host", - "runExceptLabel": "todos exceto", - "runAutoHint": "Executa em $(alert.dataSource) — o host que gerou o alerta.", - "pickHost": "escolha um host…", - "orTemplateHint": "Ou digite um modelo — $(alert.field) é resolvido por execução.", - "addExclusion": "adicionar exclusão", - "searchAgents": "buscar agentes…", - "noAgents": "sem agentes", - "insertField": "Inserir campo", - "alert": "Alerta", - "wholeOutput": "saída completa (edite o caminho)", - "noAncestorsHint": "Ainda não há ancestrais de enriquecimento — adicione um nó de enriquecimento acima para expor sua saída aqui.", - "inserts": "insere", - "conditionalHint": "Todas as condições devem corresponder. Correspondência → ramo de sucesso (verde); falha → ramo de erro (vermelho).", - "http": { - "url": "URL", - "urlInvalid": "URL http(s) inválida.", - "method": "Método", - "body": "Corpo (JSON)", - "bodyInvalid": "JSON inválido", - "headers": "Cabeçalhos HTTP", - "params": "Parâmetros da consulta", - "key": "Chave", - "value": "Valor", - "addHeader": "Adicionar cabeçalho", - "addParam": "Adicionar parâmetro" + "saving": "Salvando…", + "chips": { + "total": "tenants", + "active": "ativos", + "readable": "com acesso" }, - "incident": { - "name": "Nome do incidente", - "namePlaceholder": "Ex. Login suspeito em $(alert.dataSource)", - "description": "Descrição", - "descriptionPlaceholder": "Contexto opcional para respondentes. Modelos como $(alert.name) são interpolados." - }, - "llm": { - "prompt": "Prompt", - "hint": "O modelo é instruído a responder sempre com um único objeto JSON com a propriedade \"result\"; o backend garante esse formato mesmo se o modelo se desviar. Os nós filhos referenciam via $({{nodeId}}.result) ou campos específicos." - }, - "mail": { - "to": "Para (separados por vírgula)", - "cc": "CC (separados por vírgula, opcional)", - "addressInvalid": "Endereço de e-mail inválido: {{address}}", - "subject": "Assunto", - "subjectPlaceholder": "Ex. Alerta em $(alert.dataSource)", - "body": "Corpo", - "bodyPlaceholder": "Conteúdo da mensagem. Modelos como $(alert.name) são interpolados." - }, - "notify": { - "level": "Level", - "message": "Message", - "messagePlaceholder": "Notification text. Templates like $(alert.name) are interpolated." + "status": { + "ACTIVE": "Ativo", + "SUSPENDED": "Suspenso", + "TERMINATED": "Encerrado" + }, + "support": { + "NONE": "Sem acesso", + "READ": "Acesso de leitura", + "FULL": "Acesso total", + "hint": "Concedido pelo tenant, não por você. Só o administrador dele pode mudar isso." + }, + "card": { + "edit": "Editar", + "activate": "Ativar", + "deactivate": "Desativar", + "deletePermanent": "Excluir permanentemente", + "noAccess": "Este tenant não concedeu acesso a você.", + "loadingStats": "Lendo…", + "enter": "Entrar" + }, + "stats": { + "users": "Usuários", + "datasources": "Fontes", + "openAlerts": "Alertas abertos", + "ai": "IA hoje", + "noLimit": "sem limite" + }, + "fields": { + "name": "Nome", + "domain": "Domínio", + "domainHint": "Por onde este tenant é acessado. Toda requisição nesse host entra nos dados dele.", + "adminEmail": "E-mail do administrador", + "adminEmailHint": "Ele recebe um convite para definir a própria senha.", + "status": "Status", + "suspendedWarning": "Um tenant suspenso não consegue entrar. Os dados dele são mantidos.", + "aiLimit": "Limite de requisições de IA", + "aiLimitHint": "Um limite operacional, por dia. Sem limite, o consumo conta na licença da instância.", + "aiLimitToggle": "Limitar este tenant" + }, + "create": { + "title": "Novo tenant", + "subtitle": "Cria o tenant e convida o primeiro administrador dele.", + "submit": "Criar tenant" + }, + "edit": { + "title": "Editar tenant", + "subtitle": "O acesso de suporte não fica aqui: só o tenant pode concedê-lo.", + "submit": "Salvar alterações" + }, + "terminate": { + "title": "Desativar este tenant?", + "body": "Ninguém em {{name}} conseguirá entrar. Os dados são mantidos, então é reversível, mas o cliente fica fora agora.", + "confirmLabel": "Digite {{name}} para confirmar", + "submit": "Desativar" + }, + "reactivate": { + "title": "Ativar este tenant?", + "body": "{{name}} poderá entrar novamente. Os dados preservados são restaurados como estavam.", + "submit": "Ativar" + }, + "deletePermanent": { + "title": "Excluir este tenant para sempre?", + "body": "Todo vestígio de {{name}} — usuários, fontes de dados, dashboards, alertas, integrações — será apagado. Isso não pode ser desfeito.", + "confirmLabel": "Digite {{name}} para confirmar", + "submit": "Excluir para sempre" + }, + "toast": { + "created": "Tenant criado", + "updated": "Tenant atualizado", + "terminated": "Tenant encerrado", + "reactivated": "Tenant reativado", + "permanentlyDeleted": "Tenant excluído permanentemente", + "domainInUse": "Esse domínio já está em uso", + "noPermission": "Você não tem permissão para isso", + "notFound": "Tenant não encontrado", + "invalidRequest": "Requisição inválida", + "operationFailed": "A operação falhou" + }, + "switcher": { + "aria": "Switch tenant", + "self": "Default tenant", + "create": "Create tenant" } - } - }, - "executions": { - "search": "Buscar por ID de alerta…", - "all": "Todas", - "loading": "Carregando execuções…", - "loadError": "Não foi possível carregar as execuções.", - "retry": "Tentar de novo", - "empty": "Ainda não há execuções.", - "cols": { - "status": "Status", - "flow": "Fluxo", - "command": "Comando / Ação", - "agent": "Agente", - "date": "Data", - "retries": "Tentativas", - "node": "Nó" - }, - "filters": { - "source": "Origem", - "allSources": "Todas as origens" - }, - "manual": "Consola interativa" - }, - "executionStatus": { - "WAITING": "Aguardando", - "PENDING": "Pendente", - "EXECUTING": "Executando", - "EXECUTED": "Executado", - "FAILED": "Falhou", - "DEAD": "Inacessível" - }, - "executionOrigin": { - "FLOW": "Fluxo", - "MANUAL": "Manual" - }, - "nonExecutionCause": { - "AGENT_OFFLINE": "Agente offline", - "AGENT_NOT_FOUND": "Agente não encontrado", - "UNKNOWN": "Desconhecido" - }, - "kpi": { - "flows": "Fluxos totais", - "active": "Ativos", - "runs24h": "Execuções (24h)", - "failed24h": "Falhas (24h)" - }, - "neverRun": "nunca", - "create": { - "title": "Novo fluxo", - "modeManual": "Criar manualmente", - "modeAi": "Com IA", - "aiLocked": "Ative o SOC-AI e configure-o para usar isto.", - "name": "Nome do fluxo", - "namePlaceholder": "ex.: Bloquear IP em falhas repetidas", - "aiDescriptionLabel": "O que este fluxo deve fazer?", - "aiDescriptionPlaceholder": "ex.: Em um alerta crítico, pesquisar o IP de origem na inteligência de ameaças e bloqueá-lo no firewall", - "aiCreate": "Criar com IA", - "manualContinue": "Continuar" - } - }, - "compliance": { - "title": "Compliance", - "subtitle": "Avalie sua postura frente a frameworks de segurança — veja quais controles são atendidos e quais não.", - "comingSoon": "Em breve.", - "tabs": { - "frameworks": "Frameworks", - "schedule": "Agendamento", - "controls": "Controles" - }, - "search": "Buscar frameworks…", - "refresh": "Refresh", - "loading": "Carregando frameworks…", - "loadError": "Could not load reports", - "retry": "Tentar de novo", - "empty": "Nenhum framework corresponde.", - "notEvaluated": "Não avaliado", - "controlsCount": "{{n}} controles", - "enabledLabel": "Ativo", - "runReport": "Executar relatório", - "backToFrameworks": "Voltar aos frameworks", - "statusAuto": "Auto (avaliado)", - "overrideError": "Falha ao atualizar o status", - "noteError": "Não foi possível salvar a nota", - "notes": { - "title": "Notas", - "placeholder": "Adicionar uma nota…", - "save": "Salvar", - "cancel": "Cancelar" - }, - "reasonModal": { - "title": "Motivo obrigatório", - "description": "Informe o motivo da alteração de status. Ele será registrado.", - "label": "Motivo", - "placeholder": "Explique por que está alterando o status deste controle…", - "confirm": "Confirmar alteração", - "cancel": "Cancelar" - }, - "coverageLabel": "Cobertura", - "activityLabel": "Atividade", - "evidenceLabel": "Evidência", - "seeMore": "Ver mais", - "seeLess": "Ver menos", - "evaluating": "Avaliando framework…", - "complianceScore": "Pontuação de compliance", - "generatedAt": "Gerado {{date}}", - "reportError": "Não foi possível gerar o relatório.", - "coverage": "{{n}} regras", - "activity": "{{n}} alertas", - "status": { - "COMPLIANT": "Conforme", - "NON_COMPLIANT": "Não conforme", - "AT_RISK": "Em risco", - "NOT_COVERED": "Sem cobertura", - "OUT_OF_SCOPE": "Fora do escopo", - "PENDING": "Pendente", - "label": "Status", - "NOT_EVALUATED": "Not evaluated" - }, - "toast": { - "toggleError": "Falha ao mudar o estado do framework", - "reportGenerated": "Relatório gerado", - "reportError": "Falha ao gerar o relatório" - }, - "schedule": { - "new": "Novo agendamento", - "loading": "Carregando agendamentos…", - "loadError": "Não foi possível carregar os agendamentos.", - "empty": "Ainda não há agendamentos.", - "edit": "Editar", - "delete": "Excluir", - "newTitle": "Novo agendamento", - "editTitle": "Editar agendamento", - "framework": "Framework", - "cadenceLabel": "Cadência", - "cronHint": "Cron de 5 campos (min hora dia mês diaSemana).", - "recipientsHint": "Emails separados por vírgula. Vazio = só armazena o snapshot.", - "save": "Salvar", - "cancel": "Cancelar", - "frameworkRequired": "O framework é obrigatório", - "cronRequired": "O agendamento (cron) é obrigatório", - "cadence": { - "daily": "Diário", - "weekly": "Semanal", - "monthly": "Mensal", - "custom": "Personalizado" - }, - "toast": { - "saved": "Agendamento salvo", - "saveError": "Falha ao salvar o agendamento", - "deleted": "Agendamento excluído", - "deleteError": "Falha ao excluir o agendamento" - }, - "to": "To", - "cc": "Cc", - "toRequired": "At least one recipient is required", - "windowDays": "Reporting window (days)", - "windowDaysShort": "over {{days}}d", - "windowDaysHint": "How far back the report counts. Independent of how often it runs." - }, - "frameworks": { - "new": "Novo framework", - "edit": "Editar", - "createTitle": "Novo framework", - "visualTab": "Visual", - "codeTab": "Código", - "key": "Chave", - "name": "Nome", - "description": "Descrição", - "source": "Fonte", - "sections": "Seções", - "sectionKey": "chave da seção", - "sectionName": "Nome da seção", - "requirements": "Requisitos", - "reqId": "id req", - "reqName": "Nome do requisito", - "addSection": "Adicionar seção", - "addRequirement": "Adicionar requisito", - "satisfiedBy": "satisfeito por controles", - "searchControls": "Buscar controles…", - "noControls": "Sem controles", - "save": "Salvar", - "delete": "Excluir", - "confirmDelete": "Confirmar exclusão", - "cancel": "Cancelar", - "yamlError": "Não foi possível aplicar o YAML: {{error}}", - "keyRequired": "A chave é obrigatória", - "nameRequired": "O nome é obrigatório", - "toast": { - "created": "Framework criado", - "saved": "Framework salvo", - "saveError": "Falha ao salvar o framework", - "deleted": "Framework excluído", - "deleteError": "Falha ao excluir o framework" - }, - "createControl": "Criar novo controle…", - "createNamed": "Criar controle \"{{name}}\"…" - }, - "controls": { - "search": "Buscar controles…", - "allFamilies": "Todas as famílias", - "new": "Novo controle", - "loading": "Carregando controles…", - "loadError": "Não foi possível carregar os controles.", - "empty": "Nenhum controle corresponde.", - "showingOf": "Mostrando {{shown}} de {{total}}", - "id": "ID", - "name": "Nome", - "family": "Família", - "familyName": "Família", - "scope": "Escopo", - "source": "Fonte", - "notInLibrary": "Controle não encontrado na biblioteca", - "scopeOpt": { - "data": "Dados", - "governance": "Governança" - }, - "strategy": "Estratégia", - "statement": "Enunciado", - "remediation": "Remediação", - "checks": "Checks", - "checksHint": "Cada check executa uma consulta SQL no OpenSearch e aplica uma regra para decidir passa/falha.", - "checkKey": "chave", - "checkName": "Nome do check", - "rule": { - "MIN_HITS_REQUIRED": "Mín hits exigidos", - "THRESHOLD_MAX": "Limite máx" - }, - "ruleNone": "Sem regra", - "ruleValue": "valor", - "addCheck": "Adicionar check", - "createTitle": "Novo controle", - "visualTab": "Visual", - "codeTab": "Código", - "save": "Salvar", - "delete": "Excluir", - "confirmDelete": "Confirmar exclusão", - "cancel": "Cancelar", - "yamlError": "Não foi possível aplicar o YAML: {{error}}", - "idRequired": "O ID é obrigatório", - "nameRequired": "O nome é obrigatório", - "anyDataType": "Any data type", - "addFilter": "Add filter", - "filterField": "log.eventCode", - "filterValue": "value", - "filterValues": "a, b, c", - "toast": { - "created": "Controle criado", - "saved": "Controle salvo", - "saveError": "Falha ao salvar o controle", - "deleted": "Controle excluído", - "deleteError": "Falha ao excluir o controle" - } - }, - "doc": { - "title": "Relatório de Compliance", - "print": "Imprimir / PDF", - "controlsEvaluated": "{{n}} controles avaliados", - "executiveSummary": "Resumo Executivo", - "bySection": "Achados por Seção", - "footer": "{{framework}} — Relatório de compliance gerado {{date}} · {{brand}}", - "download": "Baixar PDF", - "downloadError": "Falha ao baixar o PDF", - "error": "Não foi possível gerar o PDF", - "building": "Gerando o documento…" - }, - "locked": { - "badge": "Enterprise", - "upgrade": "Atualizar para Enterprise", - "upsell": "Este framework/controle requer a edição Enterprise." - }, - "run": "Run evaluation", - "runError": "Evaluation failed", - "noReportYet": "This framework has not been evaluated yet.", - "window": "window {{from}} → {{to}}", - "scoredOver": "{{compliant}} of {{evaluated}} requirements met · {{total}} in the framework", - "editStale": "Recorded when the engine said {{was}}; it now says {{now}}", - "checkResults": "Check results", - "verdict": "Recorded verdict", - "engineSaid": "engine said", - "hits": "hits", - "noDataFor": "no {{dataType}} data in the window", - "setStatus": "Set status", - "outcome": { - "PASSED": "Passed", - "FAILED": "Failed", - "NOT_APPLICABLE": "No data", - "ERROR": "Error" - }, - "system": "Do sistema", - "addNote": "Adicionar nota", - "noteModal": { - "title": "Nota", - "description": "Registrada no relatório. Não altera o estado do controle.", - "placeholder": "Remediação em curso — ticket OPS-4412." - }, - "history": { - "title": "Score ao longo do tempo", - "score": "Score de conformidade", - "coverage": "Avaliados", - "error": "Não foi possível carregar o histórico" - } - }, - "taggingRules": { - "title": "Regras de Marcação", - "subtitle": "Marque automaticamente alertas que correspondam às condições.", - "new": "Nova regra", - "refresh": "Atualizar", - "empty": "Ainda não há regras de marcação.", - "loadError": "Não foi possível carregar as regras de marcação.", - "retry": "Tentar novamente", - "deleteConfirm": "Excluir a regra \"{{name}}\"? Os próximos alertas que corresponderem às suas condições deixarão de ser marcados.", - "toolbar": { - "search": "Buscar pelo nome da regra…", - "allTags": "Todas as etiquetas" - }, - "table": { - "rule": "Regra", - "tags": "Etiquetas", - "conditions": "Condições", - "modifiedBy": "Modificado por", - "modifiedDate": "Modificado" - }, - "drawer": { - "createTitle": "Nova regra de marcação", - "edit": "Editar", - "delete": "Excluir", - "save": "Salvar", - "create": "Criar", - "cancel": "Cancelar" - }, - "form": { - "basics": "Informações básicas", - "name": "Nome da regra", - "namePlaceholder": "ex.: Força bruta SSH interno", - "description": "Descrição", - "descriptionPlaceholder": "Por que esta regra existe e o que ela marca.", - "tags": "Etiquetas a aplicar", - "noTags": "Nenhuma etiqueta selecionada.", - "addTag": "Adicionar etiqueta", - "removeTag": "Remover", - "noCatalog": "Ainda não há etiquetas no catálogo.", - "createTag": "Criar etiqueta", - "newTagName": "Nome da nova etiqueta", - "conditions": "Condições (TODAS devem corresponder)", - "noConditions": "É necessária pelo menos uma condição.", - "addCondition": "Adicionar condição", - "removeCondition": "Remover condição", - "valuePlaceholder": "Valor", - "valueListPlaceholder": "Valores separados por vírgula", - "incomplete": "Preencha o nome da regra, a descrição, ao menos uma etiqueta e complete todas as condições." - }, - "view": { - "description": "Descrição", - "tags": "Etiquetas", - "conditions": "Condições", - "audit": "Auditoria", - "createdBy": "Criado por", - "createdDate": "Criado", - "modifiedBy": "Modificado por", - "modifiedDate": "Modificado" - }, - "toast": { - "created": "Regra \"{{name}}\" criada.", - "updated": "Regra \"{{name}}\" atualizada.", - "deleted": "Regra \"{{name}}\" excluída.", - "createError": "Falha ao criar a regra.", - "updateError": "Falha ao atualizar a regra.", - "deleteError": "Falha ao excluir a regra." - }, - "deleteTitle": "Excluir regra de marcação" - }, - "threatIntel": { - "header": { - "matchedInEnv": "coincidências em seu ambiente", - "export": "Exportar IOCs", - "exporting": "Exportando…", - "noInstanceIocs": "Sem indicadores de instância — exibindo dados genéricos", - "noInstanceIocsHint": "Nenhum indicador observado em seus alertas — exibindo dados genéricos dos feeds." - }, - "overview": { - "title": "Correspondências de IOC", - "totalIndicators": "indicadores totais", - "families": { - "ip": "IP", - "url": "URL", - "domain": "Domínio", - "signatures": "Assinaturas" - } - }, - "notConfigured": { - "title": "Threat Intelligence não está configurado", - "body": "Entre em contato com seu administrador para conectar uma instância do Cyber Mantra / ThreatWinds a este ambiente." - }, - "lookup": { - "title": "Pesquisar qualquer indicador", - "placeholder": "Cole um IP, domínio, hash, URL ou CVE — verificaremos os feeds e seu ambiente", - "button": "Pesquisar", - "busy": "Pesquisando…" - }, - "tabs": { - "iocs": "IOCs", - "actors": "Atores de ameaça", - "feeds": "Feeds", - "analyst": "Analista de IA" - }, - "toolbar": { - "searchPlaceholders": { - "iocs": "Pesquise valor IOC, tag, fonte…", - "actors": "Pesquise atores, aliases, técnicas…", - "feeds": "Pesquise feeds…" - }, - "last24h": "Últimas 24 horas", - "filters": "Filtros", - "refresh": "Atualizar" - }, - "iocs": { - "table": { - "type": "Tipo", - "indicator": "Indicador", - "reputation": "Reputação", - "tags": "Tags", - "lastSeen": "Visto pela última vez" - }, - "empty": "Nenhuma correspondência de IOC.", - "loadingMore": "Carregando mais…", - "loadedProgress": "Carregados {{loaded}} de {{total}}. Role para mais.", - "endOfResults": "Fim dos resultados ({{loaded}} de {{total}})." - }, - "drawer": { - "loading": "Carregando…", - "accuracy": "Precisão:", - "actions": { - "block": "Bloquear no perímetro", - "viewEvents": "Ver eventos correspondentes", - "externalLookup": "Pesquisa externa", - "trackCampaign": "Rastrear campanha", - "viewIocs": "Ver IOCs correspondentes", - "mitre": "MITRE ATT&CK" - }, - "sections": { - "timeline": "Linha do tempo", - "networkOrigin": "Rede / origem", - "associationsWithCount": "Associações ({{count}})", - "geolocationsWithCount": "Geolocalizações ({{count}})", - "about": "Sobre", - "activity": "Atividade" - }, - "fields": { - "firstSeen": "Visto pela primeira vez", - "lastSeen": "Visto pela última vez", - "country": "País", - "city": "Cidade", - "aso": "ASO", - "asn": "ASN", - "reputation": "Reputação", - "accuracy": "Precisão", - "current": "Atual", - "best": "Melhor", - "worst": "Pior" - }, - "aiBrief": "Resumo de IA", - "noDescription": "Nenhuma descrição disponível para este indicador.", - "lastObserved": "Última observação {{when}}." - }, - "actors": { - "empty": "Nenhum ator encontrado." - }, - "feeds": { - "empty": "Nenhum feed configurado.", - "table": { - "name": "Feed", - "type": "Tipo", - "accuracy": "Precisão", - "header": "Feeds", - "format": "Formato" - }, - "download": "Baixar feed", - "checksum": "Verificação" }, - "entityTypes": { - "ip": "IP", - "hostname": "Host", - "domain": "Domínio", - "url": "URL", - "hash": "Hash", - "cve": "CVE", - "threat": "Ameaça", - "entity": "Entidade" - }, - "reputation": { - "alarming": "Alarmante", - "suspicious": "Suspeito", - "indefinable": "Indefinível", - "fair": "Justo", - "trustworthy": "Confiável" - }, - "feedAccuracy": { - "level1": "Nível 1", - "level2": "Nível 2", - "level3": "Nível 3" - }, - "triage": { - "title": "Triage", - "subtitle": "Paste indicators, get verdicts", - "input": "Indicators", - "placeholder": "Paste IPs, domains, URLs or hashes — one per line, or comma separated.\nDefanged values (1.2.3[.]4, hxxp://) are accepted.", - "run": "Triage", - "stop": "Stop", - "reset": "Clear", - "parsed": "{{count}} unique indicators", - "capped": "Capped at {{max}} per run.", - "progress": "{{done}} of {{total}}", - "empty": "Paste indicators above to begin.", - "indicator": "Indicator", - "type": "Type", - "verdict": "Verdict", - "reputation": "Rep", - "accuracy": "Acc", - "tags": "Tags", - "lastSeen": "Last seen", - "exportCsv": "Export CSV", - "exportStix": "Export STIX", - "stixNote": "STIX export includes malicious and suspicious rows only.", - "open": "Open", - "notConfigured": "Threat intelligence is not configured — triage needs an upstream ThreatWinds instance.", - "summary": "Summary", - "v.malicious": "Malicious", - "v.suspicious": "Suspicious", - "v.benign": "Benign", - "v.unknown": "Unknown", - "v.notFound": "Not found", - "v.invalid": "Unrecognised" - }, - "report": { - "title": "Reportar", - "subtitle": "Publicar um indicador no grafo ThreatWinds", - "submit": "Reportar indicador", - "submitting": "Reportando…", - "error": { - "generic": "Não foi possível enviar o indicador. Tente novamente." - }, - "value": { - "label": "Indicador", - "placeholder": "IP, domínio, URL, hash ou e-mail" - }, - "type": { - "label": "Tipo", - "placeholder": "Inferido do valor", - "inferred": "Inferido: {{type}}", - "inferenceFailed": "Nenhum tipo pôde ser inferido deste valor. Escolha um da lista ou digite.", - "unknown": "“{{type}}” não é um tipo de entidade. Escolha um da lista." - }, - "tags": { - "label": "Etiquetas", - "placeholder": "phishing, roubo-de-credenciais" - }, - "description": { - "label": "Notas" - }, - "reputation": { - "legend": "Reputação", - "hint": "Deixe em branco se você não chegou a um veredito.", - "alarming": "Alarmante", - "worrying": "Preocupante", - "concerning": "Suspeito", - "indefinable": "Indefinível", - "adequate": "Adequado", - "good": "Bom", - "exceptional": "Excelente" - }, - "associations": { - "legend": "Indicadores relacionados", - "add": "Adicionar indicador relacionado", - "remove": "Remover", - "valuePlaceholder": "Valor relacionado", - "typePlaceholder": "Tipo (opcional)", - "modeLabel": "Relação", - "mode": { - "association": "Relacionado a", - "aggregation": "Parte de" - }, - "visibilityConflict": "Não compartilha nenhum grupo de visibilidade com o indicador acima. Todo o envio seria rejeitado." - }, - "attributes": { - "legend": "Detalhes", - "hint": "Opcional. Qualquer campo em branco não é enviado.", - "invalidHex": "Esperados {{length}} caracteres hexadecimais.", - "invalidHexAny": "Apenas caracteres hexadecimais.", - "invalidNumber": "Esperado um número." - }, - "correlate": { - "legend": "Correlacionar", - "hint": "Cada atributo marcado é publicado como entidade própria, vinculada a esta.", - "count_one": "Cria {{count}} entidade vinculada.", - "count_other": "Cria {{count}} entidades vinculadas." - }, - "scan": { - "notice": "Reportar isto também enfileira uma varredura do alvo." - }, - "receipt": { - "title": "Enviado", - "noVerdict": "Sem veredito", - "skipped": "Não enviado, nenhum tipo pôde ser inferido", - "pending": "Aguardando o indicador aparecer no corpus…", - "live": "No ar no corpus — ver entidade", - "processing": "Ainda em processamento. Aparecerá quando a ingestão estiver em dia.", - "another": "Reportar outro" - }, - "visibility": { - "legend": "Visível para" - }, - "example": "Tentar um exemplo" - } - }, - "playground": { - "titleFilter": "Testar pipeline", - "titleRule": "Testar regra", - "noDataTypes": "Este pipeline ainda não tem tipos de dados atribuídos — adicione um para testá-lo.", - "dataTypeLabel": "Tipo de dado", - "dataTypePlaceholder": "Nenhum tipo de dado disponível", - "dataTypeSingleHint": "Este pipeline só tem um tipo de dado — adicione mais para poder escolher.", - "rawLogLabel": "Log bruto", - "rawLogPlaceholder": "Cole uma linha de log de exemplo…", - "rawLogCounter": "{{chars}} caracteres · {{kb}} KB", - "rawLogTooLarge": "Este log excede o limite de 1 MB — reduza-o antes de executar o teste.", - "run": { - "label": "Executar", - "running": "Testando…", - "waitHint": "Isso pode levar até 15 segundos enquanto o pipeline processa o log." - }, - "errors": { - "busy": "O playground está ocupado com outro teste — tente novamente em instantes.", - "timeout": "O teste expirou — normalmente significa que o tipo de dado selecionado não corresponde ao formato do log.", - "validation": "A requisição foi inválida — verifique o log bruto e o conteúdo do pipeline.", - "server": "O playground não conseguiu concluir o teste — tente novamente." - }, - "notices": { - "geo": "O plugin de geolocalização não está disponível nesta versão lite do teste de filtros e regras.", - "correlation": "As regras que referenciam eventos anteriores por meio das cláusulas afterEvent ou correlation exigem que eventos correspondentes já existam no sistema para que o alerta em teste seja disparado." - }, - "result": { - "label": "Resultado processado", - "empty": "Execute um teste para ver aqui o evento processado.", - "loading": "Aguardando o evento processado…", - "tabs": { - "fields": "Campos", - "json": "JSON" - }, - "fieldsCount_one": "{{count}} campo", - "fieldsCount_other": "{{count}} campos", - "copy": "Copiar", - "copied": "Copiado", - "elapsed": "Processado em {{time}}", - "elapsedHint": "Tempo entre Executar e o resultado processado", - "searchPlaceholder": "Buscar campos…", - "noMatch": "Nenhum campo corresponde à sua busca." - }, - "alerts": { - "label": "Alertas", - "empty": "Execute um teste para ver aqui os alertas gerados.", - "none": "Nenhum alerta foi disparado.", - "count_one": "{{count}} alerta", - "count_other": "{{count}} alertas" - }, - "title": "Test pipeline" - }, - "tenants": { - "title": "Tenants", - "new": "Novo tenant", - "subtitle": "Cada cliente nesta instância, o que ele tem e o que deixa você ver.", - "searchPlaceholder": "Pesquisar por nome ou domínio…", - "loading": "Carregando tenants…", - "loadFailed": "Não foi possível carregar os tenants.", - "retry": "Tentar novamente", - "none": "Ainda não há tenants.", - "noSearchMatch": "Nenhum tenant corresponde à pesquisa.", - "cancel": "Cancelar", - "saving": "Salvando…", - "chips": { - "total": "tenants", - "active": "ativos", - "readable": "com acesso" - }, - "status": { - "ACTIVE": "Ativo", - "SUSPENDED": "Suspenso", - "TERMINATED": "Encerrado" - }, - "support": { - "NONE": "Sem acesso", - "READ": "Acesso de leitura", - "FULL": "Acesso total", - "hint": "Concedido pelo tenant, não por você. Só o administrador dele pode mudar isso." - }, - "card": { - "edit": "Editar", - "activate": "Ativar", - "deactivate": "Desativar", - "deletePermanent": "Excluir permanentemente", - "noAccess": "Este tenant não concedeu acesso a você.", - "loadingStats": "Lendo…", - "enter": "Entrar" - }, - "stats": { - "users": "Usuários", - "datasources": "Fontes", - "openAlerts": "Alertas abertos", - "ai": "IA hoje", - "noLimit": "sem limite" - }, - "fields": { - "name": "Nome", - "domain": "Domínio", - "domainHint": "Por onde este tenant é acessado. Toda requisição nesse host entra nos dados dele.", - "adminEmail": "E-mail do administrador", - "adminEmailHint": "Ele recebe um convite para definir a própria senha.", - "status": "Status", - "suspendedWarning": "Um tenant suspenso não consegue entrar. Os dados dele são mantidos.", - "aiLimit": "Limite de requisições de IA", - "aiLimitHint": "Um limite operacional, por dia. Sem limite, o consumo conta na licença da instância.", - "aiLimitToggle": "Limitar este tenant" - }, - "create": { - "title": "Novo tenant", - "subtitle": "Cria o tenant e convida o primeiro administrador dele.", - "submit": "Criar tenant" - }, - "edit": { - "title": "Editar tenant", - "subtitle": "O acesso de suporte não fica aqui: só o tenant pode concedê-lo.", - "submit": "Salvar alterações" - }, - "terminate": { - "title": "Desativar este tenant?", - "body": "Ninguém em {{name}} conseguirá entrar. Os dados são mantidos, então é reversível, mas o cliente fica fora agora.", - "confirmLabel": "Digite {{name}} para confirmar", - "submit": "Desativar" - }, - "reactivate": { - "title": "Ativar este tenant?", - "body": "{{name}} poderá entrar novamente. Os dados preservados são restaurados como estavam.", - "submit": "Ativar" - }, - "deletePermanent": { - "title": "Excluir este tenant para sempre?", - "body": "Todo vestígio de {{name}} — usuários, fontes de dados, dashboards, alertas, integrações — será apagado. Isso não pode ser desfeito.", - "confirmLabel": "Digite {{name}} para confirmar", - "submit": "Excluir para sempre" - }, - "toast": { - "created": "Tenant criado", - "updated": "Tenant atualizado", - "terminated": "Tenant encerrado", - "reactivated": "Tenant reativado", - "permanentlyDeleted": "Tenant excluído permanentemente", - "domainInUse": "Esse domínio já está em uso", - "noPermission": "Você não tem permissão para isso", - "notFound": "Tenant não encontrado", - "invalidRequest": "Requisição inválida", - "operationFailed": "A operação falhou" - }, - "switcher": { - "aria": "Switch tenant", - "self": "Default tenant", - "create": "Create tenant" - } - }, - "supportAccess": { - "title": "Acesso de suporte", - "intro": "Quem opera esta instância não consegue olhar dentro dos seus dados sem a sua permissão. Nada aqui é concedido por padrão, e você pode retirar quando quiser.", - "loading": "Carregando…", - "loadFailed": "Não foi possível ler a configuração atual.", - "retry": "Tentar novamente", - "currentBadge": "atual", - "save": "Salvar", - "saving": "Salvando…", - "levels": { - "NONE": { - "name": "Sem acesso", - "desc": "O operador vê que o seu tenant existe e nada mais. Qualquer requisição aos seus dados é recusada." - }, - "READ": { - "name": "Somente leitura", - "desc": "O operador pode ver seus alertas, logs e configuração para ajudar. Não pode mudar nada: toda escrita é recusada, seja qual for a função dele." - }, - "FULL": { - "name": "Acesso total", - "desc": "O operador pode agir dentro do seu tenant como administrador: configuração, usuários e fluxos de resposta." - } - }, - "fullWarning": "O acesso total permite que ele mude coisas em seu nome. Conceda enquanto precisar de ajuda direta e volte atrás depois.", - "revokeNote": "Tudo o que o operador fizer aqui fica registrado no seu log de auditoria.", - "toast": { - "granted": "Acesso de suporte atualizado", - "revoked": "Acesso de suporte revogado", - "forbidden": "Só um administrador deste tenant pode mudar isso", - "invalid": "Requisição inválida", - "failed": "Não foi possível salvar a alteração" - } - }, - "supportSession": { - "inside": "Você está trabalhando dentro de {{name}}", - "readOnly": "somente leitura — as escritas são recusadas", - "full": "acesso total — o que mudar aqui é real", - "leave": "Sair" - }, - "platformBroadcast": { - "button": "Aplicar a todos os inquilinos", - "action": { - "create": "Transmitir criação de {{resource}}", - "update": "Transmitir atualização de {{resource}}", - "delete": "Transmitir exclusão de {{resource}}", - "toggle": "Transmitir alternância de {{resource}}", - "enable": "Transmitir habilitação de {{resource}}", - "activate": "Transmitir ativação de {{resource}}", - "test": "Transmitir teste de {{resource}}", - "upload": "Transmitir ativo {{resource}}" - }, - "resource": { - "pipeline": "pipeline", - "correlationRule": "regra de correlação", - "soarFlow": "fluxo SOAR", - "framework": "estrutura", - "control": "controle", - "smtp": "SMTP", - "idp": "provedor de identidade", - "branding": "marca" - }, - "warning": { - "title": "Esta ação será executada em cada inquilino selecionado.", - "body": "Falhas por inquilino são relatadas após a execução e não são revertidas." - }, - "allTenants": "Aplicar a todos os inquilinos", - "excludesDefault": "O inquilino da plataforma é excluído desta ação.", - "searchPlaceholder": "Buscar inquilinos…", - "loading": "Carregando inquilinos…", - "empty": "Nenhum inquilino corresponde.", - "targetCount": "Alvo: {{count}} inquilino(s).", - "platformTenant": "plataforma", - "confirm": "Aplicar a {{count}} inquilino(s)", - "result": { - "succeeded": "Bem-sucedidos", - "noneSucceeded": "Nenhum inquilino teve sucesso.", - "failed": "Falhados", - "noneFailed": "Sem falhas." - } - }, - "tiAnalyst": { - "console": { - "subtitle": "Espaço do analista", - "model": "Modelo", - "resizeResults": "Redimensionar o painel de resultados", - "resizeHint": "Arraste para redimensionar · duplo clique para redefinir" - }, - "conv": { - "title": "Conversas", - "allConversations": "Todas as conversas", - "empty": "Ainda não há conversas.", - "new": "Nova conversa", - "newTitle": "Título da conversa", - "selectPrompt": "Selecione uma conversa ou comece uma.", - "running": "em andamento", - "delete": "Excluir {{title}}", - "unread_one": "{{count}} mensagem não lida", - "unread_other": "{{count}} mensagens não lidas", - "transcript": "Transcrição da conversa" - }, - "agent": { - "placeholder": "Investigar um indicador…", - "ask": "Perguntar ao agente analista", - "intro": "Pergunte sobre qualquer indicador. O agente consulta o ThreatWinds diretamente e mostra seu trabalho.", - "send": "Enviar", - "stop": "Parar", - "thinking": "pensando…", - "suggestionInvestigate": "Investigue 8.8.8.8 e me diga se é malicioso", - "suggestionInfrastructure": "Qual infraestrutura está relacionada ao google.com?", - "suggestionCounts": "Mostre-me quantas entidades existem por tipo" + "supportAccess": { + "title": "Acesso de suporte", + "intro": "Quem opera esta instância não consegue olhar dentro dos seus dados sem a sua permissão. Nada aqui é concedido por padrão, e você pode retirar quando quiser.", + "loading": "Carregando…", + "loadFailed": "Não foi possível ler a configuração atual.", + "retry": "Tentar novamente", + "currentBadge": "atual", + "save": "Salvar", + "saving": "Salvando…", + "levels": { + "NONE": { + "name": "Sem acesso", + "desc": "O operador vê que o seu tenant existe e nada mais. Qualquer requisição aos seus dados é recusada." + }, + "READ": { + "name": "Somente leitura", + "desc": "O operador pode ver seus alertas, logs e configuração para ajudar. Não pode mudar nada: toda escrita é recusada, seja qual for a função dele." + }, + "FULL": { + "name": "Acesso total", + "desc": "O operador pode agir dentro do seu tenant como administrador: configuração, usuários e fluxos de resposta." + } + }, + "fullWarning": "O acesso total permite que ele mude coisas em seu nome. Conceda enquanto precisar de ajuda direta e volte atrás depois.", + "revokeNote": "Tudo o que o operador fizer aqui fica registrado no seu log de auditoria.", + "toast": { + "granted": "Acesso de suporte atualizado", + "revoked": "Acesso de suporte revogado", + "forbidden": "Só um administrador deste tenant pode mudar isso", + "invalid": "Requisição inválida", + "failed": "Não foi possível salvar a alteração" + } }, - "canvas": { - "title": "Resultados", - "empty": "Os resultados desta conversa aparecem aqui.", - "tile": "Organizar", - "closeAll": "Fechar tudo", - "pinOut": "Abrir {{title}} como painel", - "loading": "carregando…", - "failed": "não foi possível carregar", - "noRelations": "sem entidades relacionadas", - "noGeo": "sem geolocalização registrada", - "noResults": "sem correspondências", - "matches": "{{total}} correspondências", - "panelName": "{{title}} — {{kind}}", - "movePanel": "Mover {{title}}", - "resizePanel": "Redimensionar {{title}}", - "closePanel": "Fechar {{title}}", - "collapse": "Recolher {{title}}", - "expand": "Expandir {{title}}", - "kind": { - "entity": "dossiê", - "graph": "relações", - "geo": "geolocalização", - "search": "pesquisa" - } + "supportSession": { + "inside": "Você está trabalhando dentro de {{name}}", + "readOnly": "somente leitura — as escritas são recusadas", + "full": "acesso total — o que mudar aqui é real", + "leave": "Sair" + }, + "platformBroadcast": { + "button": "Aplicar a todos os inquilinos", + "action": { + "create": "Transmitir criação de {{resource}}", + "update": "Transmitir atualização de {{resource}}", + "delete": "Transmitir exclusão de {{resource}}", + "toggle": "Transmitir alternância de {{resource}}", + "enable": "Transmitir habilitação de {{resource}}", + "activate": "Transmitir ativação de {{resource}}", + "test": "Transmitir teste de {{resource}}", + "upload": "Transmitir ativo {{resource}}" + }, + "resource": { + "pipeline": "pipeline", + "correlationRule": "regra de correlação", + "soarFlow": "fluxo SOAR", + "framework": "estrutura", + "control": "controle", + "smtp": "SMTP", + "idp": "provedor de identidade", + "branding": "marca" + }, + "warning": { + "title": "Esta ação será executada em cada inquilino selecionado.", + "body": "Falhas por inquilino são relatadas após a execução e não são revertidas." + }, + "allTenants": "Aplicar a todos os inquilinos", + "excludesDefault": "O inquilino da plataforma é excluído desta ação.", + "searchPlaceholder": "Buscar inquilinos…", + "loading": "Carregando inquilinos…", + "empty": "Nenhum inquilino corresponde.", + "targetCount": "Alvo: {{count}} inquilino(s).", + "platformTenant": "plataforma", + "confirm": "Aplicar a {{count}} inquilino(s)", + "result": { + "succeeded": "Bem-sucedidos", + "noneSucceeded": "Nenhum inquilino teve sucesso.", + "failed": "Falhados", + "noneFailed": "Sem falhas." + } }, - "graph": { - "nodes_one": "{{count}} nó", - "nodes_other": "{{count}} nós", - "edges_one": "{{count}} aresta", - "edges_other": "{{count}} arestas", - "clickToPivot": "clique para alternar", - "malicious": "malicioso", - "unknown": "desconhecido", - "benign": "inofensivo" + "tiAnalyst": { + "console": { + "subtitle": "Espaço do analista", + "model": "Modelo", + "resizeResults": "Redimensionar o painel de resultados", + "resizeHint": "Arraste para redimensionar · duplo clique para redefinir" + }, + "conv": { + "title": "Conversas", + "allConversations": "Todas as conversas", + "empty": "Ainda não há conversas.", + "new": "Nova conversa", + "newTitle": "Título da conversa", + "selectPrompt": "Selecione uma conversa ou comece uma.", + "running": "em andamento", + "delete": "Excluir {{title}}", + "unread_one": "{{count}} mensagem não lida", + "unread_other": "{{count}} mensagens não lidas", + "transcript": "Transcrição da conversa" + }, + "agent": { + "placeholder": "Investigar um indicador…", + "ask": "Perguntar ao agente analista", + "intro": "Pergunte sobre qualquer indicador. O agente consulta o ThreatWinds diretamente e mostra seu trabalho.", + "send": "Enviar", + "stop": "Parar", + "thinking": "pensando…", + "suggestionInvestigate": "Investigue 8.8.8.8 e me diga se é malicioso", + "suggestionInfrastructure": "Qual infraestrutura está relacionada ao google.com?", + "suggestionCounts": "Mostre-me quantas entidades existem por tipo" + }, + "canvas": { + "title": "Resultados", + "empty": "Os resultados desta conversa aparecem aqui.", + "tile": "Organizar", + "closeAll": "Fechar tudo", + "pinOut": "Abrir {{title}} como painel", + "loading": "carregando…", + "failed": "não foi possível carregar", + "noRelations": "sem entidades relacionadas", + "noGeo": "sem geolocalização registrada", + "noResults": "sem correspondências", + "matches": "{{total}} correspondências", + "panelName": "{{title}} — {{kind}}", + "movePanel": "Mover {{title}}", + "resizePanel": "Redimensionar {{title}}", + "closePanel": "Fechar {{title}}", + "collapse": "Recolher {{title}}", + "expand": "Expandir {{title}}", + "kind": { + "entity": "dossiê", + "graph": "relações", + "geo": "geolocalização", + "search": "pesquisa" + } + }, + "graph": { + "nodes_one": "{{count}} nó", + "nodes_other": "{{count}} nós", + "edges_one": "{{count}} aresta", + "edges_other": "{{count}} arestas", + "clickToPivot": "clique para alternar", + "malicious": "malicioso", + "unknown": "desconhecido", + "benign": "inofensivo" + }, + "entity": { + "reputation": "Reputação", + "accuracy": "Precisão", + "worst": "Pior", + "best": "Melhor", + "relations": "Grafo de relações", + "history": "Histórico", + "geolocations": "Geolocalizações", + "associations": "Associações", + "radius": "r={{radius}}m", + "askAgentBtn": "Perguntar ao agente", + "askAgent": "Avalie {{type}} {{value}} (entidade id {{id}}). É uma ameaça?" + }, + "tool": { + "querying": "consultando…", + "notRetained": "Resultado não mantido.", + "expand": "Mostrar solicitação e resultado", + "collapse": "Ocultar solicitação e resultado", + "noIntel": "«{{value}}» não tem inteligência de ameaça registrada.", + "noMatches": "Sem correspondências.", + "matches": "{{items}} correspondências para «{{query}}»", + "more": "+{{count}} mais", + "reported": "Reportado no corpus ThreatWinds compartilhado. A ingestao e assincrona, nao imediatamente pesquisavel.", + "skippedAssociations": "Nao registrado (tipo nao inferivel): {{values}}" + } }, - "entity": { - "reputation": "Reputação", - "accuracy": "Precisão", - "worst": "Pior", - "best": "Melhor", - "relations": "Grafo de relações", - "history": "Histórico", - "geolocations": "Geolocalizações", - "associations": "Associações", - "radius": "r={{radius}}m", - "askAgentBtn": "Perguntar ao agente", - "askAgent": "Avalie {{type}} {{value}} (entidade id {{id}}). É uma ameaça?" + "threatwinds": { + "title": "Integração ThreatWinds", + "subtitle": "Partilhe os incidentes desta instância com o feed comunitário da ThreatWinds.", + "feeds": "Ativar feeds", + "feedsHint": "Quando ativado, os eventos são verificados em relação aos feeds de inteligência da ThreatWinds.", + "contribute": "Contribuir com incidentes", + "contributeHint": "Quando ativado, os incidentes desta instância são enviados para a ThreatWinds.", + "loading": "A carregar estado da integração…", + "failed": "Não foi possível carregar o estado da integração ThreatWinds.", + "retry": "Tentar novamente", + "toast": { + "enabled": "Contribuição ativada", + "disabled": "Contribuição desativada", + "failed": "Não foi possível atualizar a configuração de contribuição" + } }, - "tool": { - "querying": "consultando…", - "notRetained": "Resultado não mantido.", - "expand": "Mostrar solicitação e resultado", - "collapse": "Ocultar solicitação e resultado", - "noIntel": "«{{value}}» não tem inteligência de ameaça registrada.", - "noMatches": "Sem correspondências.", - "matches": "{{items}} correspondências para «{{query}}»", - "more": "+{{count}} mais", - "reported": "Reportado no corpus ThreatWinds compartilhado. A ingestao e assincrona, nao imediatamente pesquisavel.", - "skippedAssociations": "Nao registrado (tipo nao inferivel): {{values}}" - } - }, - "threatwinds": { - "title": "Integração ThreatWinds", - "subtitle": "Partilhe os incidentes desta instância com o feed comunitário da ThreatWinds.", - "feeds": "Ativar feeds", - "feedsHint": "Quando ativado, os eventos são verificados em relação aos feeds de inteligência da ThreatWinds.", - "contribute": "Contribuir com incidentes", - "contributeHint": "Quando ativado, os incidentes desta instância são enviados para a ThreatWinds.", - "loading": "A carregar estado da integração…", - "failed": "Não foi possível carregar o estado da integração ThreatWinds.", - "retry": "Tentar novamente", - "toast": { - "enabled": "Contribuição ativada", - "disabled": "Contribuição desativada", - "failed": "Não foi possível atualizar a configuração de contribuição" - } - }, - "liveOps": { - "header": "Operações ao vivo", - "live": "AO VIVO", - "replay": "REPRODUÇÃO", - "statLastHour": "Última hora", - "statHigh": "Altas", - "statOpen": "Abertas", - "statAttackers": "Atacantes", - "listTitle": "Alertas", - "listShown": "{{count}} mostradas", - "listShow": "Mostrar a lista de alertas", - "listHide": "Ocultar a lista", - "agoJust": "agora", - "agoMin": "há {{count}} min", - "agoH": "há {{count}} h", - "more": "Mais", - "less": "Menos", - "loading": "A carregar alertas…", - "error": "Não foi possível carregar os alertas: {{msg}}", - "empty": "Não há alertas no repositório.", - "onStage": "Em cena", - "hideDetails": "Ocultar este painel", - "showDetails": "Mostrar os detalhes", - "inIncident": "Num incidente", - "openInAlerts": "Abrir em Alertas", - "involved": "Envolvidos", - "askSocAi": "Perguntar a SOC-AI", - "askExplain": "Explica este ataque e diz-me o que fazer a seguir", - "askFp": "É um falso positivo?", - "askAttacker": "O que mais fez este atacante?", - "timCount": "{{count}} alertas nas últimas {{range}}", - "timPrev": "Alerta anterior", - "timNext": "Alerta seguinte", - "timReplay": "Reproduzir janela", - "timStop": "Parar reprodução", - "timLive": "AO VIVO", - "timNow": "agora", - "kb": { - "bruteForce": "Força bruta", - "outbound": "Ligação para um destino malicioso", - "lateral": "Movimento lateral", - "malware": "Execução maliciosa num host", - "webAttack": "Ataque web", - "travel": "Viagem impossível", - "scan": "Varredura de portas", - "cloud": "Alteração arriscada na cloud", - "generic": "Deteção", - "ransomware": "Ransomware em um host", - "persistence": "Mecanismo de persistência", - "exfil": "Exfiltração de dados", - "defenseEvasion": "Evasão de defesas", - "privEsc": "Escalação de privilégios", - "userExec": "Usuário abre arquivo malicioso", - "softwareDeploy": "Software empurrada para um host", - "phishing": "E-mail de phishing aberta", - "processInjection": "Código injetado em um processo", - "credDump": "Credenciais roubadas", - "dataDestruction": "Dados destruídos", - "toolDownload": "Ferramenta baixada e executada", - "c2tunnel": "C2 por túnel", - "iocMatch": "IOC de ameaça detectado", - "perimeterDetect": "Detecção de perímetro/IDS", - "accountChange": "Alteração de conta ou política", - "kerberosTicket": "Abuso de ticket Kerberos", - "powershellAbuse": "Abuso de scripting", - "reverseShell": "Shell reversa", - "vmEscape": "Escape VM/hipervisor" + "liveOps": { + "header": "Operações ao vivo", + "live": "AO VIVO", + "replay": "REPRODUÇÃO", + "statLastHour": "Última hora", + "statHigh": "Altas", + "statOpen": "Abertas", + "statAttackers": "Atacantes", + "listTitle": "Alertas", + "listShown": "{{count}} mostradas", + "listShow": "Mostrar a lista de alertas", + "listHide": "Ocultar a lista", + "agoJust": "agora", + "agoMin": "há {{count}} min", + "agoH": "há {{count}} h", + "more": "Mais", + "less": "Menos", + "loading": "A carregar alertas…", + "error": "Não foi possível carregar os alertas: {{msg}}", + "empty": "Não há alertas no repositório.", + "onStage": "Em cena", + "hideDetails": "Ocultar este painel", + "showDetails": "Mostrar os detalhes", + "inIncident": "Num incidente", + "openInAlerts": "Abrir em Alertas", + "involved": "Envolvidos", + "askSocAi": "Perguntar a SOC-AI", + "askExplain": "Explica este ataque e diz-me o que fazer a seguir", + "askFp": "É um falso positivo?", + "askAttacker": "O que mais fez este atacante?", + "timCount": "{{count}} alertas nas últimas {{range}}", + "timPrev": "Alerta anterior", + "timNext": "Alerta seguinte", + "timReplay": "Reproduzir janela", + "timStop": "Parar reprodução", + "timLive": "AO VIVO", + "timNow": "agora", + "kb": { + "bruteForce": "Força bruta", + "outbound": "Ligação para um destino malicioso", + "lateral": "Movimento lateral", + "malware": "Execução maliciosa num host", + "webAttack": "Ataque web", + "travel": "Viagem impossível", + "scan": "Varredura de portas", + "cloud": "Alteração arriscada na cloud", + "generic": "Deteção", + "ransomware": "Ransomware em um host", + "persistence": "Mecanismo de persistência", + "exfil": "Exfiltração de dados", + "defenseEvasion": "Evasão de defesas", + "privEsc": "Escalação de privilégios", + "userExec": "Usuário abre arquivo malicioso", + "softwareDeploy": "Software empurrada para um host", + "phishing": "E-mail de phishing aberta", + "processInjection": "Código injetado em um processo", + "credDump": "Credenciais roubadas", + "dataDestruction": "Dados destruídos", + "toolDownload": "Ferramenta baixada e executada", + "c2tunnel": "C2 por túnel", + "iocMatch": "IOC de ameaça detectado", + "perimeterDetect": "Detecção de perímetro/IDS", + "accountChange": "Alteração de conta ou política", + "kerberosTicket": "Abuso de ticket Kerberos", + "powershellAbuse": "Abuso de scripting", + "reverseShell": "Shell reversa", + "vmEscape": "Escape VM/hipervisor" + }, + "replayTip": "Reproduzir todas as alertas desta janela em ordem", + "liveTip": "Seguir as novas alertas à medida que chegam", + "playAgain": "Reproduzir esta alerta novamente", + "alertAt": "{{name}} às {{time}}", + "netInternet": "Internet", + "netInternal": "Rede interna", + "scUser": "utilizador: {{account}}", + "scWrongPassword": "✕ palavra-passe incorreta", + "scSignedIn": "✓ sessão iniciada", + "scSignedInAs": "início de sessão como {{account}}", + "scFailedSignins": "Falhas de início de sessão", + "scBlocked": "🛡 {{name}} bloqueado", + "scSessionAs": "sessão como {{account}}", + "scHost": "Host · {{name}}", + "scFiles": "Documentos", + "scBackups": "Cópias de sombra", + "scRansomNote": "🔒 NOTA DE RESGATE", + "scShadows": "✕ cópias de sombra excluídas", + "scPersist": "Persistência", + "scReboot": "sobrevive a reinícios: porta dos fundos instalada", + "scCloud": "Armazenamento externo", + "scChunk": "dados", + "scExfilBytes": "Dados exfiltrados", + "scProcessTree": "Árvore de processos", + "scDns": "DNS? {{host}}", + "scThreatIntel": "Intel de ameaças: Alarmante (-3)", + "scConnDropped": "✕ ligação terminada", + "scPortsProbed": "Portas exploradas", + "scSignIn": "✓ início de sessão", + "scKmInMin": "{{km}} km em {{min}} min", + "scAbroad": "no estrangeiro", + "scDropped": "{{status}} rejeitado", + "scBeacon": "baliza", + "capBrute0": "{{name}}{{sub}} começa a adivinhar palavras-passe contra {{where}}.", + "capBruteVpn": "a VPN em {{name}}", + "capBrute1": "{{attempts}} inícios de sessão falhados em {{minutes}} minutos, a rodar {{count}} nomes de conta.", + "capBrute2": "Um início de sessão como {{account}} tem sucesso logo a seguir às falhas: a palavra-passe foi adivinhada.", + "capBrute3": "Correlação das falhas entre fontes: um atacante, muitas contas.", + "capBrute4": "Bloqueia {{name}} no perímetro{{reset}}.", + "capBruteReset": " e repõe {{account}}", + "capOut1": "{{who}} procura {{dest}}.", + "capOut2": "Liga-se para fora na porta {{port}}{{through}}.", + "capOutThrough": " através de {{name}}", + "capOut3": "A inteligência de ameaças corresponde a {{dest}}: {{kind}}.", + "capOut4": "A ligação foi terminada e a alerta foi levantada para que a máquina seja verificada.", + "capOut5": "A ligação repete-se: {{name}} provavelmente está infetado. Isola-o e encontra o processo.", + "capLat0": "{{name}}{{user}} contacta {{to}} dentro da rede.", + "capLatUser": " ({{user}})", + "capLat1": "Autentica-se como {{account}} usando {{how}}.", + "capLatHowHash": "um hash de palavra-passe roubado", + "capLatHowKerb": "bilhetes de serviço Kerberos que pode quebrar fora da linha", + "capLatHowAsrep": "uma resposta Kerberos para uma conta sem pré-autenticação", + "capLatHowSmb": "o antigo protocolo SMBv1", + "capLatHowRdp": "sessões remotas e partilhas de ficheiros", + "capLat2": "{{to}} aceita a sessão: o atacante agora se move entre máquinas.", + "capLat3": "Desativa {{account}} e verifica as duas máquinas.", + "capMal0": "Em {{host}}{{user}} executa-se {{proc}}.", + "capMalUser": ", {{user}}", + "capMal1": "{{p0}} inicia {{p1}}: incomum para este programa.", + "capMalChild": "um processo filho", + "capMal2": "{{name}} executa: {{detail}}.", + "capMalKnown": "uma técnica de ataque conhecida", + "capMal3": "Para o processo ou isola {{host}}.", + "capWeb0": "{{name}} sonda o servidor em {{to}}.", + "capWeb1": "Envia cargas de ataque: {{payloads}}…", + "capWeb2": "{{perimeter}} reconhece as assinaturas do ataque e descarta as requisições.", + "capWeb2b": "A IPS reconhece as assinaturas do ataque e descarta as requisições.", + "capWeb3": "Algunas requisições chegam a {{to}}; o servidor responde com erros e um 200 OK.", + "capWeb4": "Bloqueia {{name}} e verifica os registos do servidor.", + "capTrv0": "{{user}} inicia sessão desde {{city}}, como de costume.", + "capTrv1": "{{gap}} minutos depois, a mesma conta inicia sessão desde {{city}}, {{country}}.", + "capTrvFar": "longe", + "capTrv2": "{{km}} km em {{gap}} minutos: ninguém viaja tão depressa. A palavra-passe provavelmente foi roubada.", + "capTrv3": "Revoga as sessões e repõe a palavra-passe de {{user}}.", + "capScn0": "{{name}} começa a bater em {{to}}, uma porta atrás da outra.", + "capScn1": "{{count}} portas exploradas em segundos: SSH, SMB, RDP, bases de dados, consolas web…", + "capScn2": "As portas {{open}} respondem; o resto está fechado ou filtrado.", + "capScn3": "Normalmente o primeiro passo de um ataque: bloqueia a origem.", + "capCl0": "{{name}} inicia sessão em {{cloud}}{{from}}.", + "capClFrom": " desde {{country}}", + "capClFromDef": "fora da empresa", + "capCl1": "Mudam {{what}}.", + "capCl3": "Confirma se estava planeado, ou desfaz.", + "capGen0": "{{src}} → {{tgt}}", + "capGen1": "{{what}}", + "capGenNew": "Nova deteção", + "capGen2": "Alerta levantado: {{name}}.", + "capAlertRaised": "Alerta levantado: {{name}}. ", + "capBlocked": "{{ip}} está agora bloqueado em {{on}}: o tráfego para aqui.", + "destUnknown": "destino desconhecido", + "titleBrute": "Força bruta a partir de {{name}} contra {{to}}", + "titleOut": "{{name}} a contactar {{to}}", + "titleLat": "{{name}} a mover-se para {{to}} como {{account}}", + "titleMal": "{{name}} em {{to}}", + "titleWeb": "Ataque web a partir de {{name}} contra {{to}}", + "titleTrv": "{{name}} inicia sessão a partir de dois continentes", + "titleScn": "Exploração de portas a partir de {{name}}", + "titleCl": "{{what}} alterado em {{to}}", + "titleAlert": "Alerta", + "dLsass": "esvazia a memória do LSASS para roubar palavras-passe", + "dMiner": "mina criptomoeda com a CPU do servidor", + "dRev": "abre uma shell interactiva de volta ao atacante", + "dKey": "exporta palavras-passe guardadas do keychain", + "dTask": "cria uma tarefa que executa um payload a cada início de sessão", + "dAudit": "apaga o registo de segurança do Windows", + "dFw": "apaga as regras do firewall do host", + "dShadow": "apaga as cópias de sombra do volume antes de cifrar", + "dDump": "ferramenta de extração de credenciais", + "dDl": "descarrega uma ferramenta para uma pasta gravável", + "dPs": "executa um comando codificado", + "capRan0": "Em {{host}}{{user}}, um processo começa a tocar centenas de arquivos de uma vez.", + "capRanUser": ", {{user}}", + "capRan1": "Os arquivos são renomeados com {{exts}}: os dados são criptografados no local.", + "capRan2": "Uma nota de resgate é escrita: o atacante pede pagamento para restaurar os dados.", + "capRan2b": "Os backups e as cópias de sombra são excluídos: sem retorno fácil.", + "capRan3": "Restaurar dos backups offline e encontrar o ponto de entrada antes que a criptografia se espalhe.", + "titleRan": "Ransomware criptografando {{to}}", + "capPer0": "Em {{host}}{{user}}, algo está escrevendo nos locais de inicialização do sistema.", + "capPer1": "Ele solta {{what}}: esses executam automaticamente a cada boot ou login.", + "capPer2": "Última peça no lugar: {{what}}. A presença agora sobrevive a reinícios.", + "capPer3": "Remover os artefatos de persistência e procurar o vetor de infecção inicial.", + "titlePer": "Persistência instalada em {{to}} via {{what}}", + "dPersistCron": "executa o payload conforme um agendador", + "dPersistSd": "inicia o payload a cada boot", + "dPersistLaunch": "inicia o payload quando o usuário faz login", + "dPersistKey": "permite ao atacante voltar por SSH", + "dPersistRc": "executa o payload em cada novo shell", + "dPersistPs": "executa o payload em cada sessão PowerShell", + "dPersistPay": "o próprio binário do payload", + "capExf0": "Em {{host}}{{user}}, dados sensíveis são reunidos em um arquivo.", + "capExf1": "Começa a transferi-los para fora usando {{tool}}.", + "capExf2": "Os dados chegam a {{dest}}: agora estão fora da empresa.", + "capExf3": "Bloquear a transferência, revogar o acesso a {{dest}} e descobrir quem pode alcançá-los.", + "titleExf": "{{name}} exfiltrando dados para {{to}}", + "scDefenses": "Defesas", + "scDisabled": "✕ desativado", + "scLogsCleared": "🗑 logs apagados", + "dEvLog": "trilha de auditoria", + "dEvEnf": "aplicação", + "capEv0": "Em {{host}}, o atacante começa a tocar nas coisas que o vigiam.", + "capEv1": "{{what}} é desativado: uma a menos que pode vê-lo.", + "capEv2": "Os logs são apagados: o rastro de suas ações desaparece.", + "capEv2b": "Com {{what}} desativado, o host fica cego diante do atacante.", + "capEv3": "Restaurar as ferramentas desativadas e preservar os logs restantes antes que desapareçam também.", + "titleEv": "Defesas desativadas em {{to}}", + "scNormalUser": "usuário normal", + "scToken": "token", + "dEvUac": "UAC contornada", + "dEvToken": "token suplantado", + "dEvSuid": "binário setuid abusado", + "dEvSudo": "cache do sudo abusado", + "dEvExploit": "kernel explorado", + "dEvDefault": "fronteira de privilégios cruzada", + "capPe0": "Em {{host}}, a sessão roda como usuário normal.{{user}}", + "capPeUser": ", {{user}}", + "capPe1": "Ele usa {{method}} para alcançar um nível de privilégio maior.", + "capPe2": "Os comandos agora rodam como {{account}}: controle total do host.", + "capPe3": "Encerrar a sessão escalada e auditar o que {{account}} pôde tocar.", + "titlePe": "Escalação de privilégios em {{to}} via {{method}}", + "alertRaised": "Alerta levantado", + "userExec": "Usuário abre arquivo malicioso", + "softwareDeploy": "Software empurrada para um host", + "phishing": "E-mail de phishing aberta", + "processInjection": "Código injetado em um processo", + "credDump": "Credenciais roubadas", + "dataDestruction": "Dados destruídos", + "toolDownload": "Ferramenta baixada e executada", + "c2tunnel": "C2 por túnel", + "scExec": "Execução", + "scPayload": "→ payload malicioso", + "capUe0": "Em {{host}}{{user}}, o usuário baixa um arquivo e o abre.", + "capUeUser": ", {{user}}", + "capUe1": "O arquivo é aberto: {{file}} é confiável e executado.", + "capUe2": "{{app}} inicia um processo filho que executa {{payload}}.", + "capUe3": "Colocar o arquivo em quarentena, bloquear seu hash e verificar outros hosts que o abriram.", + "titleUe": "{{file}} aberto em {{to}}", + "scDeploy": "Implantação", + "capSd0": "{{src}} empurra software para {{to}} pela rede.", + "capSd1": "Usa {{tool}}: um canal que instala sem interação do usuário.", + "capSd2": "O pacote é instalado em {{to}} e inicia com ele.", + "capSd3": "Parar a implantação, remover o componente instalado e auditar o que ele fez.", + "titleSd": "Software implantada de {{src}} para {{to}}", + "scAttachment": "anexo aberto", + "capPh0": "{{name}} envia um e-mail de phishing para a empresa.", + "capPh1": "A mensagem chega à caixa de {{user}} e é aberta.", + "capPh2": "O anexo é executado: {{file}} roda na máquina.", + "capPh3": "Colocar o e-mail em quarentena, bloquear o remetente e remover {{file}} da máquina de {{user}}.", + "titlePh": "E-mail de phishing aberto por {{user}} (de {{from}})", + "scInject": "Injeção", + "scInside": "— código dentro de um processo confiável", + "capPi0": "Em {{host}}, o carregador do atacante começa: {{injector}}.", + "capPi1": "Ele injeta código em um processo confiável: {{victim}}.", + "capPi2": "{{victim}} agora executa o código do atacante com seus próprios privilégios.", + "capPi3": "Matar o código injetado, remover o carregador e procurar outras vítimas.", + "titlePi": "{{injector}} injeta código em {{victim}}", + "scCred": "Armazenário de credenciais", + "scSecrets": "{{n}} segredos", + "scSecret": "segredo", + "scStolen": "✕ credenciais roubadas", + "capCd0": "Em {{host}}, uma ferramenta começa a ler o armazenário de credenciais.", + "capCd1": "Ela abre {{store}} e extrai o material armazenado.", + "capCd2": "{{n}} credenciais são capturadas: contas, chaves e hashes.", + "capCd3": "Rotacionar todas as credenciais do armazenário e caçar a ferramenta de dump.", + "titleCd": "{{store}} roubado em {{host}}", + "scData": "Dados", + "scDataItem": "dados-{{i}}", + "scGone": "perdido", + "scNoRecovery": "dados destruídos", + "capDd0": "Em {{host}}, algo começa a apagar dados em vez de criptografá-los.", + "capDd1": "{{n}} conjuntos de dados são destruídos, um após o outro.", + "capDd2": "Os dados são apagados em bruto: sem nota, sem resgate, sem volta.", + "capDd3": "Parar o processo de origem e restaurar o que resta dos backups offline.", + "titleDd": "Dados destruídos em {{host}}", + "scDownload": "bytes", + "scExecuted": "executado", + "capTd0": "{{src}} entrega uma ferramenta para {{to}}.", + "capTd1": "Ela é baixada para uma pasta gravável: {{folder}}.", + "capTd2": "O arquivo é executado: {{tool}} está agora rodando.", + "capTd3": "Excluir a ferramenta, bloquear seu hash e verificar quais hosts a executaram.", + "titleTd": "{{src}} deixa uma ferramenta em {{to}}", + "scTunnel": "oculto em tráfego {{proto}}", + "scTunneled": "Bytes em túnel", + "capCt0": "{{src}} conversa com {{to}} usando um protocolo que parece normal.", + "capCt1": "O payload está escondido no tráfego {{proto}}.", + "capCt2": "Comandos e dados cruzam a fronteira invisíveis, montados em {{proto}}.", + "capCt3": "Cortar o túnel, bloquear o destino e verificar o que passou por ele.", + "titleCt": "{{src}} faz túnel de C2 via {{proto}} para {{to}}", + "netPerimeter": "Perímetro", + "scDc": "Controlador de domínio", + "scObject": "Objeto modificado", + "scChangedBy": "modificado por", + "scHighRisk": "alteração de alto risco", + "scTktAsk": "pedido de ticket", + "scTktUses": "reutilizado em {{n}} serviços", + "scTerminal": "Terminal", + "scRunning": "…executando", + "scAmsiOff": "⚠ AMSI desativado", + "scConn": "TCP {{port}}", + "scShellOn": "$ shell reversa", + "scHypervisor": "Hipervisor", + "scGuestVm": "máquina virtual convidada", + "scConfined": "confinado ao convidado", + "scEscaped": "escapou para o host", + "scBoundary": "fronteira do convidado cruzada", + "scFeedAsk": "feed? {{ioc}}", + "scFeedBad": "RUIM", + "scFeedHit": "Intel de ameaça: {{kind}}", + "scDroppedAtFw": "✕ descartado em {{fw}}", + "scTrafficStops": "o tráfego para aqui", + "scSigHits": "Acertos de assinatura", + "capIoc0": "{{src}} se conecta a {{ioc}}.", + "capIoc1": "A inteligência de ameaças o marca: {{kind}}.", + "capIoc2": "{{ioc}} está na lista de bloqueio: a conexão é cortada.", + "capIoc3": "Bloquear {{ioc}} na borda e verificar o que já saiu da rede.", + "titleIoc": "{{src}} atinge um {{ioc}} conhecido", + "capPd0": "{{name}} envia uma {{sig}} para o perímetro.", + "capPd1": "{{fw}} matcha a assinatura e dispara.", + "capPd2": "O tráfego é descartado: o perímetro segurou.", + "capPd3": "O tráfego cruza {{fw}}: o alerta é informativo.", + "capPd4": "Revisar a assinatura e bloquear a fonte se continuar chegando.", + "titlePd": "{{sig}} bloqueado em {{fw}}", + "capAc0": "{{who}} altera {{what}} em {{host}}.", + "capAc1": "O {{what}} é modificado.", + "capAc2": "{{before}} → {{after}}.", + "capAc3": "Confirmar que estava planejado ou reverter a alteração de {{who}}.", + "titleAc": "{{what}} alterado em {{host}}", + "capKb0": "{{src}} pede tickets Kerberos para {{dc}}.", + "capKb1": "O {{ticket}} obtido é {{kind}}.", + "capKb2": "É reutilizado em {{services}}: o DC aceita a cada vez.", + "capKb3": "Resetar a senha krbtgt e auditar os tickets emitidos nas últimas 48 h.", + "titleKb": "{{src}} forja tickets Kerberos via {{dc}}", + "capPs0": "Em {{host}}, um script inicia com conteúdo codificado.", + "capPs1": "Decodifica um comando e desativa o sensor antimalware (AMSI).", + "capPs2": "O comando decodificado executa: é um payload, não um script.", + "capPs2a": "AMSI é desativado primeiro, então o comando codificado roda sem ser visto.", + "capPs3": "Bloquear o hash, caçar outras máquinas com o mesmo script.", + "titlePs2": "Script codificado executando em {{host}}", + "capRs0": "Em {{host}}, um processo abre um socket para fora.", + "capRs1": "Ele se reconecta a {{name}} na porta {{port}}: uma shell reversa.", + "capRs2": "Um prompt aparece: o atacante já pode digitar comandos no host.", + "capRs3": "Matar a conexão, isolar {{host}} e ver o que foi digitado.", + "titleRs": "Shell reversa aberta em {{host}}", + "capVm0": "A VM convidada {{guest}} roda um processo com acesso de host.", + "capVm1": "Ele tenta cruzar a fronteira do hipervisor.", + "capVm2": "O processo roda no host {{host}}: o convidado não é mais uma jaula.", + "capVm3": "Panicar o hipervisor, fazer snapshot do convidado e reconstruí-lo.", + "titleVm": "Convidado {{guest}} escapando para {{host}}", + "listNew": "Nova", + "newAlertsCount_one": "{{count}} nova alerta", + "newAlertsCount_other": "{{count}} novas alertas", + "statTotal": "Total", + "timPage": "Página {{p}}/{{n}}", + "timPagePrev": "Página anterior", + "timPageNext": "Página seguinte", + "newAlerts": "Novas alertas" }, - "replayTip": "Reproduzir todas as alertas desta janela em ordem", - "liveTip": "Seguir as novas alertas à medida que chegam", - "playAgain": "Reproduzir esta alerta novamente", - "alertAt": "{{name}} às {{time}}", - "netInternet": "Internet", - "netInternal": "Rede interna", - "scUser": "utilizador: {{account}}", - "scWrongPassword": "✕ palavra-passe incorreta", - "scSignedIn": "✓ sessão iniciada", - "scSignedInAs": "início de sessão como {{account}}", - "scFailedSignins": "Falhas de início de sessão", - "scBlocked": "🛡 {{name}} bloqueado", - "scSessionAs": "sessão como {{account}}", - "scHost": "Host · {{name}}", - "scFiles": "Documentos", - "scBackups": "Cópias de sombra", - "scRansomNote": "🔒 NOTA DE RESGATE", - "scShadows": "✕ cópias de sombra excluídas", - "scPersist": "Persistência", - "scReboot": "sobrevive a reinícios: porta dos fundos instalada", - "scCloud": "Armazenamento externo", - "scChunk": "dados", - "scExfilBytes": "Dados exfiltrados", - "scProcessTree": "Árvore de processos", - "scDns": "DNS? {{host}}", - "scThreatIntel": "Intel de ameaças: Alarmante (-3)", - "scConnDropped": "✕ ligação terminada", - "scPortsProbed": "Portas exploradas", - "scSignIn": "✓ início de sessão", - "scKmInMin": "{{km}} km em {{min}} min", - "scAbroad": "no estrangeiro", - "scDropped": "{{status}} rejeitado", - "scBeacon": "baliza", - "capBrute0": "{{name}}{{sub}} começa a adivinhar palavras-passe contra {{where}}.", - "capBruteVpn": "a VPN em {{name}}", - "capBrute1": "{{attempts}} inícios de sessão falhados em {{minutes}} minutos, a rodar {{count}} nomes de conta.", - "capBrute2": "Um início de sessão como {{account}} tem sucesso logo a seguir às falhas: a palavra-passe foi adivinhada.", - "capBrute3": "Correlação das falhas entre fontes: um atacante, muitas contas.", - "capBrute4": "Bloqueia {{name}} no perímetro{{reset}}.", - "capBruteReset": " e repõe {{account}}", - "capOut1": "{{who}} procura {{dest}}.", - "capOut2": "Liga-se para fora na porta {{port}}{{through}}.", - "capOutThrough": " através de {{name}}", - "capOut3": "A inteligência de ameaças corresponde a {{dest}}: {{kind}}.", - "capOut4": "A ligação foi terminada e a alerta foi levantada para que a máquina seja verificada.", - "capOut5": "A ligação repete-se: {{name}} provavelmente está infetado. Isola-o e encontra o processo.", - "capLat0": "{{name}}{{user}} contacta {{to}} dentro da rede.", - "capLatUser": " ({{user}})", - "capLat1": "Autentica-se como {{account}} usando {{how}}.", - "capLatHowHash": "um hash de palavra-passe roubado", - "capLatHowKerb": "bilhetes de serviço Kerberos que pode quebrar fora da linha", - "capLatHowAsrep": "uma resposta Kerberos para uma conta sem pré-autenticação", - "capLatHowSmb": "o antigo protocolo SMBv1", - "capLatHowRdp": "sessões remotas e partilhas de ficheiros", - "capLat2": "{{to}} aceita a sessão: o atacante agora se move entre máquinas.", - "capLat3": "Desativa {{account}} e verifica as duas máquinas.", - "capMal0": "Em {{host}}{{user}} executa-se {{proc}}.", - "capMalUser": ", {{user}}", - "capMal1": "{{p0}} inicia {{p1}}: incomum para este programa.", - "capMalChild": "um processo filho", - "capMal2": "{{name}} executa: {{detail}}.", - "capMalKnown": "uma técnica de ataque conhecida", - "capMal3": "Para o processo ou isola {{host}}.", - "capWeb0": "{{name}} sonda o servidor em {{to}}.", - "capWeb1": "Envia cargas de ataque: {{payloads}}…", - "capWeb2": "{{perimeter}} reconhece as assinaturas do ataque e descarta as requisições.", - "capWeb2b": "A IPS reconhece as assinaturas do ataque e descarta as requisições.", - "capWeb3": "Algunas requisições chegam a {{to}}; o servidor responde com erros e um 200 OK.", - "capWeb4": "Bloqueia {{name}} e verifica os registos do servidor.", - "capTrv0": "{{user}} inicia sessão desde {{city}}, como de costume.", - "capTrv1": "{{gap}} minutos depois, a mesma conta inicia sessão desde {{city}}, {{country}}.", - "capTrvFar": "longe", - "capTrv2": "{{km}} km em {{gap}} minutos: ninguém viaja tão depressa. A palavra-passe provavelmente foi roubada.", - "capTrv3": "Revoga as sessões e repõe a palavra-passe de {{user}}.", - "capScn0": "{{name}} começa a bater em {{to}}, uma porta atrás da outra.", - "capScn1": "{{count}} portas exploradas em segundos: SSH, SMB, RDP, bases de dados, consolas web…", - "capScn2": "As portas {{open}} respondem; o resto está fechado ou filtrado.", - "capScn3": "Normalmente o primeiro passo de um ataque: bloqueia a origem.", - "capCl0": "{{name}} inicia sessão em {{cloud}}{{from}}.", - "capClFrom": " desde {{country}}", - "capClFromDef": "fora da empresa", - "capCl1": "Mudam {{what}}.", - "capCl3": "Confirma se estava planeado, ou desfaz.", - "capGen0": "{{src}} → {{tgt}}", - "capGen1": "{{what}}", - "capGenNew": "Nova deteção", - "capGen2": "Alerta levantado: {{name}}.", - "capAlertRaised": "Alerta levantado: {{name}}. ", - "capBlocked": "{{ip}} está agora bloqueado em {{on}}: o tráfego para aqui.", - "destUnknown": "destino desconhecido", - "titleBrute": "Força bruta a partir de {{name}} contra {{to}}", - "titleOut": "{{name}} a contactar {{to}}", - "titleLat": "{{name}} a mover-se para {{to}} como {{account}}", - "titleMal": "{{name}} em {{to}}", - "titleWeb": "Ataque web a partir de {{name}} contra {{to}}", - "titleTrv": "{{name}} inicia sessão a partir de dois continentes", - "titleScn": "Exploração de portas a partir de {{name}}", - "titleCl": "{{what}} alterado em {{to}}", - "titleAlert": "Alerta", - "dLsass": "esvazia a memória do LSASS para roubar palavras-passe", - "dMiner": "mina criptomoeda com a CPU do servidor", - "dRev": "abre uma shell interactiva de volta ao atacante", - "dKey": "exporta palavras-passe guardadas do keychain", - "dTask": "cria uma tarefa que executa um payload a cada início de sessão", - "dAudit": "apaga o registo de segurança do Windows", - "dFw": "apaga as regras do firewall do host", - "dShadow": "apaga as cópias de sombra do volume antes de cifrar", - "dDump": "ferramenta de extração de credenciais", - "dDl": "descarrega uma ferramenta para uma pasta gravável", - "dPs": "executa um comando codificado", - "capRan0": "Em {{host}}{{user}}, um processo começa a tocar centenas de arquivos de uma vez.", - "capRanUser": ", {{user}}", - "capRan1": "Os arquivos são renomeados com {{exts}}: os dados são criptografados no local.", - "capRan2": "Uma nota de resgate é escrita: o atacante pede pagamento para restaurar os dados.", - "capRan2b": "Os backups e as cópias de sombra são excluídos: sem retorno fácil.", - "capRan3": "Restaurar dos backups offline e encontrar o ponto de entrada antes que a criptografia se espalhe.", - "titleRan": "Ransomware criptografando {{to}}", - "capPer0": "Em {{host}}{{user}}, algo está escrevendo nos locais de inicialização do sistema.", - "capPer1": "Ele solta {{what}}: esses executam automaticamente a cada boot ou login.", - "capPer2": "Última peça no lugar: {{what}}. A presença agora sobrevive a reinícios.", - "capPer3": "Remover os artefatos de persistência e procurar o vetor de infecção inicial.", - "titlePer": "Persistência instalada em {{to}} via {{what}}", - "dPersistCron": "executa o payload conforme um agendador", - "dPersistSd": "inicia o payload a cada boot", - "dPersistLaunch": "inicia o payload quando o usuário faz login", - "dPersistKey": "permite ao atacante voltar por SSH", - "dPersistRc": "executa o payload em cada novo shell", - "dPersistPs": "executa o payload em cada sessão PowerShell", - "dPersistPay": "o próprio binário do payload", - "capExf0": "Em {{host}}{{user}}, dados sensíveis são reunidos em um arquivo.", - "capExf1": "Começa a transferi-los para fora usando {{tool}}.", - "capExf2": "Os dados chegam a {{dest}}: agora estão fora da empresa.", - "capExf3": "Bloquear a transferência, revogar o acesso a {{dest}} e descobrir quem pode alcançá-los.", - "titleExf": "{{name}} exfiltrando dados para {{to}}", - "scDefenses": "Defesas", - "scDisabled": "✕ desativado", - "scLogsCleared": "🗑 logs apagados", - "dEvLog": "trilha de auditoria", - "dEvEnf": "aplicação", - "capEv0": "Em {{host}}, o atacante começa a tocar nas coisas que o vigiam.", - "capEv1": "{{what}} é desativado: uma a menos que pode vê-lo.", - "capEv2": "Os logs são apagados: o rastro de suas ações desaparece.", - "capEv2b": "Com {{what}} desativado, o host fica cego diante do atacante.", - "capEv3": "Restaurar as ferramentas desativadas e preservar os logs restantes antes que desapareçam também.", - "titleEv": "Defesas desativadas em {{to}}", - "scNormalUser": "usuário normal", - "scToken": "token", - "dEvUac": "UAC contornada", - "dEvToken": "token suplantado", - "dEvSuid": "binário setuid abusado", - "dEvSudo": "cache do sudo abusado", - "dEvExploit": "kernel explorado", - "dEvDefault": "fronteira de privilégios cruzada", - "capPe0": "Em {{host}}, a sessão roda como usuário normal.{{user}}", - "capPeUser": ", {{user}}", - "capPe1": "Ele usa {{method}} para alcançar um nível de privilégio maior.", - "capPe2": "Os comandos agora rodam como {{account}}: controle total do host.", - "capPe3": "Encerrar a sessão escalada e auditar o que {{account}} pôde tocar.", - "titlePe": "Escalação de privilégios em {{to}} via {{method}}", - "alertRaised": "Alerta levantado", - "userExec": "Usuário abre arquivo malicioso", - "softwareDeploy": "Software empurrada para um host", - "phishing": "E-mail de phishing aberta", - "processInjection": "Código injetado em um processo", - "credDump": "Credenciais roubadas", - "dataDestruction": "Dados destruídos", - "toolDownload": "Ferramenta baixada e executada", - "c2tunnel": "C2 por túnel", "scExec": "Execução", "scPayload": "→ payload malicioso", "capUe0": "Em {{host}}{{user}}, o usuário baixa um arquivo e o abre.", @@ -6512,133 +6664,5 @@ "capCt1": "O payload está escondido no tráfego {{proto}}.", "capCt2": "Comandos e dados cruzam a fronteira invisíveis, montados em {{proto}}.", "capCt3": "Cortar o túnel, bloquear o destino e verificar o que passou por ele.", - "titleCt": "{{src}} faz túnel de C2 via {{proto}} para {{to}}", - "netPerimeter": "Perímetro", - "scDc": "Controlador de domínio", - "scObject": "Objeto modificado", - "scChangedBy": "modificado por", - "scHighRisk": "alteração de alto risco", - "scTktAsk": "pedido de ticket", - "scTktUses": "reutilizado em {{n}} serviços", - "scTerminal": "Terminal", - "scRunning": "…executando", - "scAmsiOff": "⚠ AMSI desativado", - "scConn": "TCP {{port}}", - "scShellOn": "$ shell reversa", - "scHypervisor": "Hipervisor", - "scGuestVm": "máquina virtual convidada", - "scConfined": "confinado ao convidado", - "scEscaped": "escapou para o host", - "scBoundary": "fronteira do convidado cruzada", - "scFeedAsk": "feed? {{ioc}}", - "scFeedBad": "RUIM", - "scFeedHit": "Intel de ameaça: {{kind}}", - "scDroppedAtFw": "✕ descartado em {{fw}}", - "scTrafficStops": "o tráfego para aqui", - "scSigHits": "Acertos de assinatura", - "capIoc0": "{{src}} se conecta a {{ioc}}.", - "capIoc1": "A inteligência de ameaças o marca: {{kind}}.", - "capIoc2": "{{ioc}} está na lista de bloqueio: a conexão é cortada.", - "capIoc3": "Bloquear {{ioc}} na borda e verificar o que já saiu da rede.", - "titleIoc": "{{src}} atinge um {{ioc}} conhecido", - "capPd0": "{{name}} envia uma {{sig}} para o perímetro.", - "capPd1": "{{fw}} matcha a assinatura e dispara.", - "capPd2": "O tráfego é descartado: o perímetro segurou.", - "capPd3": "O tráfego cruza {{fw}}: o alerta é informativo.", - "capPd4": "Revisar a assinatura e bloquear a fonte se continuar chegando.", - "titlePd": "{{sig}} bloqueado em {{fw}}", - "capAc0": "{{who}} altera {{what}} em {{host}}.", - "capAc1": "O {{what}} é modificado.", - "capAc2": "{{before}} → {{after}}.", - "capAc3": "Confirmar que estava planejado ou reverter a alteração de {{who}}.", - "titleAc": "{{what}} alterado em {{host}}", - "capKb0": "{{src}} pede tickets Kerberos para {{dc}}.", - "capKb1": "O {{ticket}} obtido é {{kind}}.", - "capKb2": "É reutilizado em {{services}}: o DC aceita a cada vez.", - "capKb3": "Resetar a senha krbtgt e auditar os tickets emitidos nas últimas 48 h.", - "titleKb": "{{src}} forja tickets Kerberos via {{dc}}", - "capPs0": "Em {{host}}, um script inicia com conteúdo codificado.", - "capPs1": "Decodifica um comando e desativa o sensor antimalware (AMSI).", - "capPs2": "O comando decodificado executa: é um payload, não um script.", - "capPs2a": "AMSI é desativado primeiro, então o comando codificado roda sem ser visto.", - "capPs3": "Bloquear o hash, caçar outras máquinas com o mesmo script.", - "titlePs2": "Script codificado executando em {{host}}", - "capRs0": "Em {{host}}, um processo abre um socket para fora.", - "capRs1": "Ele se reconecta a {{name}} na porta {{port}}: uma shell reversa.", - "capRs2": "Um prompt aparece: o atacante já pode digitar comandos no host.", - "capRs3": "Matar a conexão, isolar {{host}} e ver o que foi digitado.", - "titleRs": "Shell reversa aberta em {{host}}", - "capVm0": "A VM convidada {{guest}} roda um processo com acesso de host.", - "capVm1": "Ele tenta cruzar a fronteira do hipervisor.", - "capVm2": "O processo roda no host {{host}}: o convidado não é mais uma jaula.", - "capVm3": "Panicar o hipervisor, fazer snapshot do convidado e reconstruí-lo.", - "titleVm": "Convidado {{guest}} escapando para {{host}}", - "listNew": "Nova", - "newAlertsCount_one": "{{count}} nova alerta", - "newAlertsCount_other": "{{count}} novas alertas", - "statTotal": "Total", - "timPage": "Página {{p}}/{{n}}", - "timPagePrev": "Página anterior", - "timPageNext": "Página seguinte", - "newAlerts": "Novas alertas" - }, - "scExec": "Execução", - "scPayload": "→ payload malicioso", - "capUe0": "Em {{host}}{{user}}, o usuário baixa um arquivo e o abre.", - "capUeUser": ", {{user}}", - "capUe1": "O arquivo é aberto: {{file}} é confiável e executado.", - "capUe2": "{{app}} inicia um processo filho que executa {{payload}}.", - "capUe3": "Colocar o arquivo em quarentena, bloquear seu hash e verificar outros hosts que o abriram.", - "titleUe": "{{file}} aberto em {{to}}", - "scDeploy": "Implantação", - "capSd0": "{{src}} empurra software para {{to}} pela rede.", - "capSd1": "Usa {{tool}}: um canal que instala sem interação do usuário.", - "capSd2": "O pacote é instalado em {{to}} e inicia com ele.", - "capSd3": "Parar a implantação, remover o componente instalado e auditar o que ele fez.", - "titleSd": "Software implantada de {{src}} para {{to}}", - "scAttachment": "anexo aberto", - "capPh0": "{{name}} envia um e-mail de phishing para a empresa.", - "capPh1": "A mensagem chega à caixa de {{user}} e é aberta.", - "capPh2": "O anexo é executado: {{file}} roda na máquina.", - "capPh3": "Colocar o e-mail em quarentena, bloquear o remetente e remover {{file}} da máquina de {{user}}.", - "titlePh": "E-mail de phishing aberto por {{user}} (de {{from}})", - "scInject": "Injeção", - "scInside": "— código dentro de um processo confiável", - "capPi0": "Em {{host}}, o carregador do atacante começa: {{injector}}.", - "capPi1": "Ele injeta código em um processo confiável: {{victim}}.", - "capPi2": "{{victim}} agora executa o código do atacante com seus próprios privilégios.", - "capPi3": "Matar o código injetado, remover o carregador e procurar outras vítimas.", - "titlePi": "{{injector}} injeta código em {{victim}}", - "scCred": "Armazenário de credenciais", - "scSecrets": "{{n}} segredos", - "scSecret": "segredo", - "scStolen": "✕ credenciais roubadas", - "capCd0": "Em {{host}}, uma ferramenta começa a ler o armazenário de credenciais.", - "capCd1": "Ela abre {{store}} e extrai o material armazenado.", - "capCd2": "{{n}} credenciais são capturadas: contas, chaves e hashes.", - "capCd3": "Rotacionar todas as credenciais do armazenário e caçar a ferramenta de dump.", - "titleCd": "{{store}} roubado em {{host}}", - "scData": "Dados", - "scDataItem": "dados-{{i}}", - "scGone": "perdido", - "scNoRecovery": "dados destruídos", - "capDd0": "Em {{host}}, algo começa a apagar dados em vez de criptografá-los.", - "capDd1": "{{n}} conjuntos de dados são destruídos, um após o outro.", - "capDd2": "Os dados são apagados em bruto: sem nota, sem resgate, sem volta.", - "capDd3": "Parar o processo de origem e restaurar o que resta dos backups offline.", - "titleDd": "Dados destruídos em {{host}}", - "scDownload": "bytes", - "scExecuted": "executado", - "capTd0": "{{src}} entrega uma ferramenta para {{to}}.", - "capTd1": "Ela é baixada para uma pasta gravável: {{folder}}.", - "capTd2": "O arquivo é executado: {{tool}} está agora rodando.", - "capTd3": "Excluir a ferramenta, bloquear seu hash e verificar quais hosts a executaram.", - "titleTd": "{{src}} deixa uma ferramenta em {{to}}", - "scTunnel": "oculto em tráfego {{proto}}", - "scTunneled": "Bytes em túnel", - "capCt0": "{{src}} conversa com {{to}} usando um protocolo que parece normal.", - "capCt1": "O payload está escondido no tráfego {{proto}}.", - "capCt2": "Comandos e dados cruzam a fronteira invisíveis, montados em {{proto}}.", - "capCt3": "Cortar o túnel, bloquear o destino e verificar o que passou por ele.", - "titleCt": "{{src}} faz túnel de C2 via {{proto}} para {{to}}" + "titleCt": "{{src}} faz túnel de C2 via {{proto}} para {{to}}" } diff --git a/frontend/src/shared/i18n/locales/ru.json b/frontend/src/shared/i18n/locales/ru.json index 7e75769b8..53e24c591 100644 --- a/frontend/src/shared/i18n/locales/ru.json +++ b/frontend/src/shared/i18n/locales/ru.json @@ -1,6487 +1,6641 @@ { - "onboarding": { - "adminEmail": { - "title": "Укажите email администратора", - "subtitle": "Требуется перед продолжением", - "description": "Учётная запись администратора всё ещё использует email по умолчанию. Укажите настоящий адрес — он нужен для восстановления пароля, уведомлений и писем с оповещениями.", - "emailLabel": "Адрес электронной почты", - "save": "Сохранить и продолжить", - "saving": "Сохранение…", - "success": "Email администратора задан. Далее настройте почтовый сервер.", - "error": "Не удалось сохранить email. Попробуйте ещё раз." - } - }, - "common": { - "appName": "UTMStack", - "language": "Язык", - "actions": { - "save": "Сохранить", - "cancel": "Отмена", - "retry": "Повторить", - "refresh": "Обновить", - "delete": "Удалить", - "remove": "Убрать", - "close": "Закрыть", - "next": "Далее", - "back": "Назад" - }, - "confirm": { - "delete": "Удалить", - "working": "Выполняется…" - }, - "dateRange": { - "pick": "Выбрать диапазон", - "clear": "Очистить", - "done": "Готово", - "apply": "Применить" - }, - "loadingMore": "Загрузка ещё…", - "allLoaded": "Загружено: {{count}}", - "startFrom": { - "scratch": "С нуля", - "scratchHint": "Пустое определение, которое вы заполните сами.", - "copy": "На основе существующего", - "copyHint": "Копируется всё, кроме идентификатора и названия.", - "pickTitle": "Выберите, что скопировать", - "back": "Назад", - "count": "доступно: {{n}}", - "search": "Поиск по названию", - "none": "Ничего не найдено" - }, - "cancel": "Отмена" - }, - "auth": { - "login": { - "title": "С возвращением", - "subtitle": "Войдите, чтобы продолжить в {{brand}}", - "loginLabel": "Электронная почта", - "passwordLabel": "Пароль", - "forgot": "Забыли?", - "submit": "Войти", - "terms": "Выполняя вход, вы принимаете условия использования {{brand}}.", - "orContinueWith": "или продолжить через", - "continueWith": "Продолжить через {{name}}", - "signingInTo": "Вход через {{name}}", - "useAnother": "Выбрать другой" - }, - "tfa": { - "title": "Двухфакторная проверка", - "subtitleTotp": "Введите 6-значный код из приложения-аутентификатора.", - "subtitleEmail": "Введите 6-значный код, отправленный на вашу почту.", - "codeLabel": "Код подтверждения", - "submit": "Подтвердить", - "back": "Назад ко входу" + "onboarding": { + "adminEmail": { + "title": "Укажите email администратора", + "subtitle": "Требуется перед продолжением", + "description": "Учётная запись администратора всё ещё использует email по умолчанию. Укажите настоящий адрес — он нужен для восстановления пароля, уведомлений и писем с оповещениями.", + "emailLabel": "Адрес электронной почты", + "save": "Сохранить и продолжить", + "saving": "Сохранение…", + "success": "Email администратора задан. Далее настройте почтовый сервер.", + "error": "Не удалось сохранить email. Попробуйте ещё раз." + } }, - "forgot": { - "title": "Сброс пароля", - "subtitle": "Мы отправим вам ссылку для установки нового пароля.", - "emailLabel": "Эл. почта", - "submit": "Отправить ссылку", - "sent": "Если эта почта зарегистрирована, ссылка для сброса уже в пути." + "common": { + "appName": "UTMStack", + "language": "Язык", + "actions": { + "save": "Сохранить", + "cancel": "Отмена", + "retry": "Повторить", + "refresh": "Обновить", + "delete": "Удалить", + "remove": "Убрать", + "close": "Закрыть", + "next": "Далее", + "back": "Назад" + }, + "confirm": { + "delete": "Удалить", + "working": "Выполняется…" + }, + "dateRange": { + "pick": "Выбрать диапазон", + "clear": "Очистить", + "done": "Готово", + "apply": "Применить" + }, + "loadingMore": "Загрузка ещё…", + "allLoaded": "Загружено: {{count}}", + "startFrom": { + "scratch": "С нуля", + "scratchHint": "Пустое определение, которое вы заполните сами.", + "copy": "На основе существующего", + "copyHint": "Копируется всё, кроме идентификатора и названия.", + "pickTitle": "Выберите, что скопировать", + "back": "Назад", + "count": "доступно: {{n}}", + "search": "Поиск по названию", + "none": "Ничего не найдено" + }, + "cancel": "Отмена" + }, + "auth": { + "login": { + "title": "С возвращением", + "subtitle": "Войдите, чтобы продолжить в {{brand}}", + "loginLabel": "Электронная почта", + "passwordLabel": "Пароль", + "forgot": "Забыли?", + "submit": "Войти", + "terms": "Выполняя вход, вы принимаете условия использования {{brand}}.", + "orContinueWith": "или продолжить через", + "continueWith": "Продолжить через {{name}}", + "signingInTo": "Вход через {{name}}", + "useAnother": "Выбрать другой" + }, + "tfa": { + "title": "Двухфакторная проверка", + "subtitleTotp": "Введите 6-значный код из приложения-аутентификатора.", + "subtitleEmail": "Введите 6-значный код, отправленный на вашу почту.", + "codeLabel": "Код подтверждения", + "submit": "Подтвердить", + "back": "Назад ко входу" + }, + "forgot": { + "title": "Сброс пароля", + "subtitle": "Мы отправим вам ссылку для установки нового пароля.", + "emailLabel": "Эл. почта", + "submit": "Отправить ссылку", + "sent": "Если эта почта зарегистрирована, ссылка для сброса уже в пути." + }, + "errors": { + "tooManyAttempts": "Слишком много попыток. Повторите через несколько минут.", + "deactivated": "Эта учётная запись деактивирована.", + "invalidCredentials": "Неверные учётные данные.", + "codeExpired": "Срок действия кода истёк. Войдите снова.", + "loginFailed": "Не удалось войти. Попробуйте ещё раз.", + "invalidCode": "Неверный или просроченный код.", + "verifyFailed": "Не удалось подтвердить. Попробуйте ещё раз.", + "resetFailed": "Не удалось отправить письмо для сброса. Попробуйте ещё раз.", + "ssoFailed": "Единый вход не завершён. Попробуйте снова или используйте пароль." + } }, - "errors": { - "tooManyAttempts": "Слишком много попыток. Повторите через несколько минут.", - "deactivated": "Эта учётная запись деактивирована.", - "invalidCredentials": "Неверные учётные данные.", - "codeExpired": "Срок действия кода истёк. Войдите снова.", - "loginFailed": "Не удалось войти. Попробуйте ещё раз.", - "invalidCode": "Неверный или просроченный код.", - "verifyFailed": "Не удалось подтвердить. Попробуйте ещё раз.", - "resetFailed": "Не удалось отправить письмо для сброса. Попробуйте ещё раз.", - "ssoFailed": "Единый вход не завершён. Попробуйте снова или используйте пароль." - } - }, - "profile": { - "hero": { - "administrator": "Администратор", - "changeAvatar": "Изменить аватар", - "removeAvatar": "Удалить аватар" + "profile": { + "hero": { + "administrator": "Администратор", + "changeAvatar": "Изменить аватар", + "removeAvatar": "Удалить аватар" + }, + "personal": { + "title": "Личная информация", + "description": "Обновите имя и контактные данные.", + "firstName": "Имя", + "lastName": "Фамилия", + "email": "Эл. почта", + "language": "Язык", + "languageHint": "Используется для интерфейса панели.", + "systemDefault": "Системный по умолчанию", + "username": "Имя пользователя", + "usernameHint": "Имя пользователя изменить нельзя.", + "reset": "Сбросить", + "save": "Сохранить изменения", + "saving": "Сохранение…", + "name": "Имя" + }, + "password": { + "title": "Пароль", + "description": "Используйте надёжный пароль, который не используете больше нигде.", + "current": "Текущий пароль", + "new": "Новый пароль", + "newHint": "Не менее 8 символов.", + "confirm": "Подтвердите новый пароль", + "update": "Обновить пароль", + "updating": "Обновление…" + }, + "sessions": { + "title": "Активные сеансы", + "description": "Устройства, на которых выполнен вход в вашу учётную запись.", + "loading": "Загрузка сеансов…", + "empty": "Нет активных сеансов.", + "thisDevice": "Это устройство", + "unknownIp": "Неизвестный IP", + "unknownDevice": "Неизвестное устройство", + "deviceLabel": "{{browser}} на {{os}}", + "signedIn": "Вход {{time}}", + "revoke": "Отозвать", + "revoking": "Отзыв…", + "signOutOthers": "Выйти из всех других сеансов", + "signingOut": "Выход…" + }, + "tfa": { + "title": "Двухфакторная аутентификация", + "description": "Добавьте дополнительный уровень защиты вашей учётной записи.", + "loading": "Загрузка…", + "methodTotp": "Приложение-аутентификатор", + "methodEmail": "Код по эл. почте", + "onTitle": "Двухфакторная аутентификация включена", + "method": "Метод: {{method}}", + "configured": "Настроено", + "disable": "Отключить", + "disableTitle": "Отключить двухфакторную аутентификацию", + "disableDescription": "Введите текущий пароль для подтверждения. После этого учётная запись будет защищена только паролем.", + "currentPasswordPlaceholder": "Текущий пароль", + "disableConfirm": "Отключить 2FA", + "disabling": "Отключение…", + "offTitle": "Двухфакторная аутентификация выключена", + "status": "Статус:", + "notConfigured": "Не настроено", + "enable": "Включить", + "chooseMethod": "Выберите метод", + "totpDesc": "Используйте Google Authenticator, 1Password и т. п. Рекомендуется.", + "emailDesc": "Получайте 6-значный код по эл. почте при входе.", + "noEmailHint": "Добавьте эл. почту в профиль, чтобы использовать метод по почте.", + "continue": "Продолжить", + "starting": "Запуск…", + "scanTitle": "Отсканируйте QR-код", + "scanDescription": "Отсканируйте его приложением-аутентификатором, затем введите показанный 6-значный код.", + "manualKey": "Или введите этот ключ вручную:", + "checkEmailTitle": "Проверьте почту", + "checkEmailDescription": "Мы отправили 6-значный код на {{email}}. Введите его ниже.", + "resend": "Отправить снова", + "verifyEnable": "Подтвердить и включить", + "verifying": "Проверка…" + }, + "actions": { + "cancel": "Отмена" + }, + "toast": { + "profileUpdated": "Профиль обновлён", + "emailInUse": "Эта эл. почта уже используется", + "profileUpdateFailed": "Не удалось обновить профиль", + "passwordsNoMatch": "Пароли не совпадают", + "passwordTooShort": "Пароль должен содержать не менее 8 символов", + "passwordChanged": "Пароль изменён — другие сеансы завершены", + "currentPasswordWrong": "Неверный текущий пароль", + "passwordChangeFailed": "Не удалось изменить пароль", + "avatarTypeNotAllowed": "Недопустимый тип изображения (используйте PNG, JPEG, WEBP или GIF)", + "avatarTooLarge": "Изображение слишком большое (макс. 2 МБ)", + "avatarUpdated": "Аватар обновлён", + "avatarUploadFailed": "Не удалось загрузить аватар", + "avatarRemoved": "Аватар удалён", + "avatarRemoveFailed": "Не удалось удалить аватар", + "sessionsLoadFailed": "Не удалось загрузить сеансы", + "sessionRevoked": "Сеанс отозван", + "sessionRevokeFailed": "Не удалось отозвать сеанс", + "othersSignedOut": "Другие сеансы завершены", + "othersRevokeFailed": "Не удалось отозвать сеансы", + "tfaEmailCodeSent": "Мы отправили 6-значный код на вашу почту", + "tfaNewCodeSent": "Новый код отправлен", + "tfaWaitResend": "Подождите немного перед запросом нового кода", + "tfaResendFailed": "Не удалось отправить код повторно", + "tfaEnterCode": "Введите 6-значный код", + "tfaEnabled": "Двухфакторная аутентификация включена", + "tfaEnterPassword": "Введите текущий пароль", + "tfaDisabled": "Двухфакторная аутентификация отключена", + "tfaDisableFailed": "Не удалось отключить 2FA", + "tfaInvalidCode": "Неверный или просроченный код", + "tfaAlreadyEnabled": "2FA уже включена", + "tfaTooManyRequests": "Слишком много запросов; повторите чуть позже", + "tfaVerifyFailed": "Не удалось проверить код", + "genericError": "Что-то пошло не так", + "tfaMailUnavailable": "Второй фактор по почте требует почтового сервера. Настройте его в Настройки → Конфигурация почты." + } }, - "personal": { - "title": "Личная информация", - "description": "Обновите имя и контактные данные.", - "firstName": "Имя", - "lastName": "Фамилия", - "email": "Эл. почта", - "language": "Язык", - "languageHint": "Используется для интерфейса панели.", - "systemDefault": "Системный по умолчанию", - "username": "Имя пользователя", - "usernameHint": "Имя пользователя изменить нельзя.", - "reset": "Сбросить", - "save": "Сохранить изменения", - "saving": "Сохранение…", - "name": "Имя" + "home": { + "hero": { + "title": "Что вы хотите узнать из ваших данных безопасности?", + "placeholder": "Изучите Scattered Spider, применимо ли это к нам?, атаковали ли нас когда-нибудь?, создайте правило обнаружения и поддерживайте его в актуальном состоянии.", + "send": "Отправить", + "suggestions": { + "threatHunt": "Поиск угроз", + "observableTriage": "Триаж индикаторов", + "writeRule": "Написать правило", + "systemStatus": "Текущее состояние системы" + } + }, + "kpis": { + "alerts24h": "Оповещения (24 ч)", + "openIncidents": "Открытые инциденты", + "openIncidentsSub": "сейчас открыты", + "highSeverity24h": "Высокая важность (24 ч)", + "highSeveritySub": "из {{n}} оповещений", + "activePlaybooks": "Активные плейбуки", + "activePlaybooksSub": "включены" + }, + "datasources": { + "title": "Источники данных", + "viewAll": "Показать все", + "ofTotal": "из {{n}}", + "datasources": "источников данных", + "sendingData": "отправляют данные", + "totalEvents": "Всего событий", + "noData": "Нет данных о приёме в этом интервале" + }, + "span": { + "recent": "недавний период", + "days_one": "последний {{count}} день", + "days_few": "последние {{count}} дня", + "days_many": "последние {{count}} дней", + "days_other": "последние {{count}} дней", + "hours": "последние {{n}} ч" + }, + "mitre": { + "title": "Топ техник MITRE ATT&CK", + "explore": "Изучить", + "empty": "Пока нет оповещений с указанной техникой" + }, + "assets": { + "title": "Наиболее атакуемые активы", + "viewAll": "Показать все", + "asset": "Актив", + "alerts": "Оповещения", + "empty": "Нет атакуемых активов в недавних оповещениях" + }, + "compliance": { + "title": "Оценка соответствия", + "reports": "Отчёты", + "empty": "Отчёты о соответствии ещё не созданы" + }, + "health": { + "title": "Состояние системы", + "details": "Подробности", + "services": { + "backend": "Backend API", + "opensearch": "Кластер OpenSearch", + "socai": "Движок SOC-AI" + }, + "detail": { + "noClusterInfo": "нет данных о кластере", + "disabled": "отключено", + "tools": "инструментов: {{n}}", + "unreachable": "недоступен", + "pending": "…" + } + } }, - "password": { - "title": "Пароль", - "description": "Используйте надёжный пароль, который не используете больше нигде.", - "current": "Текущий пароль", - "new": "Новый пароль", - "newHint": "Не менее 8 символов.", - "confirm": "Подтвердите новый пароль", - "update": "Обновить пароль", - "updating": "Обновление…" + "nav": { + "home": "Главная", + "dashboards": "Панели", + "dashboardList": "Список панелей", + "visualizationList": "Список виджетов", + "newDashboard": "Новая панель", + "newVisualization": "Новый виджет", + "threatManagement": "Управление угрозами", + "alerts": "Оповещения", + "incidents": "Инциденты", + "adversaryView": "Обзор противников", + "soar": "SOAR", + "flows": "Потоки", + "executionHistory": "История выполнений", + "interactiveConsole": "Интерактивная консоль", + "logExplorer": "Обозреватель логов", + "userAuditor": "Аудит пользователей", + "threatIntelligence": "Аналитика угроз", + "threat-intel": { + "indicators": "Индикаторы", + "analyzt": "ИИ-аналитик", + "triage": "Триаж", + "report": "Отчёт" + }, + "compliance": "Соответствие", + "configure": "Настройка", + "dataSources": "Источники данных", + "integrations": "Интеграции", + "alertingRules": "Правила оповещений", + "dataProcessing": "Обработка данных", + "team": "Команда", + "settings": "Настройки", + "back": "Назад", + "regexPatterns": "Регулярные выражения", + "taggingRules": "Правила тегирования", + "parsingFilters": "Пайплайны", + "overview": "Обзор", + "tenants": "Арендаторы", + "openMenu": "Открыть меню", + "closeMenu": "Закрыть меню", + "liveOps": "Мониторинг онлайн" + }, + "dashboards": { + "title": "Панели", + "subtitle": "Просмотр и редактирование интерактивных панелей.", + "list": { + "title": "Панели", + "create": "Создать", + "searchPlaceholder": "Поиск панелей…", + "loading": "Загрузка панелей…", + "empty": "Панелей пока нет.", + "rename": "Переименовать", + "delete": "Удалить" + }, + "actions": { + "edit": "Редактировать", + "editWithAi": "Изменить с помощью ИИ" + }, + "refresh": { + "title": "Автообновление", + "options": { + "off": "Выкл", + "10s": "10 с", + "30s": "30 с", + "1m": "1 мин", + "5m": "5 мин", + "15m": "15 мин" + } + }, + "editor": { + "editing": "Редактирование", + "addWidget": "Добавить виджет", + "save": "Сохранить", + "discard": "Отменить", + "newTitle": "Новый виджет", + "newSubtitle": "Выберите тип диаграммы и источник данных, настройте её визуально. SQL-запрос будет создан автоматически.", + "editTitle": "Редактирование виджета", + "editSubtitle": "Настройте определение диаграммы. Изменения будут применены везде, где используется этот виджет.", + "loading": "Загрузка виджета…", + "notFoundTitle": "Виджет не найден", + "notFoundSubtitle": "Возможно, она была удалена или у вас нет к ней доступа.", + "backToDashboard": "Вернуться к панели", + "chartType": { + "title": "Тип диаграммы" + }, + "chartTypes": { + "bar": { + "label": "Столбцы", + "description": "Сравнение значений по категориям." + }, + "line": { + "label": "Линия", + "description": "Тренды по упорядоченной оси." + }, + "area": { + "label": "Область", + "description": "Заполненная линия — подчёркивает объём." + }, + "pie": { + "label": "Круговая", + "description": "Доля от целого по категориям." + }, + "metric": { + "label": "Метрика", + "description": "Одиночное скалярное значение." + }, + "table": { + "label": "Таблица", + "description": "Агрегированные строки." + }, + "list": { + "label": "Список", + "description": "Исходные строки без агрегации." + }, + "region_map": { + "label": "Карта координат", + "description": "Размещение меток на карте мира по координатам широты и долготы." + }, + "text": { + "label": "Текст", + "description": "Свободный текст или построчный вывод." + } + }, + "dataSource": { + "title": "Какие данные?", + "dataset": "Набор данных", + "noDatasetHint": "Выберите набор данных, чтобы включить условия и группировку." + }, + "widgetTitle": { + "label": "Заголовок", + "placeholder": "Необязательно — по умолчанию тип диаграммы" + }, + "dataset": { + "placeholder": "Выберите набор данных…", + "loading": "Загрузка наборов данных…" + }, + "filters": { + "title": "Включать только события, где…", + "empty": "Без условий — включаются все события за выбранный период.", + "add": "Добавить условие", + "remove": "Удалить", + "field": "Поле", + "fieldPlaceholder": "напр. host.name", + "operator": "Оператор", + "value": "Значение", + "valuePlaceholder": "Значение", + "from": "От", + "to": "До", + "noValue": "Значение не требуется", + "listPlaceholder": "Значения через запятую" + }, + "operators": { + "IS": "равно", + "IS_NOT": "не равно", + "IS_ONE_OF_TERMS": "одно из", + "IS_GREATER_THAN": "больше чем", + "IS_LESS_THAN_OR_EQUALS": "меньше или равно", + "IS_BETWEEN": "в диапазоне", + "CONTAIN": "содержит", + "DOES_NOT_CONTAIN": "не содержит", + "START_WITH": "начинается с", + "ENDS_WITH": "заканчивается на", + "EXIST": "существует", + "DOES_NOT_EXIST": "не существует" + }, + "dimension": { + "title": "Группировать по", + "field": "Поле", + "placeholder": "Выберите поле для группировки…" + }, + "table": { + "hint": "Показывает все поля записей. Добавьте столбцы, чтобы выбрать нужные.", + "columnsTitle": "Столбцы", + "allColumns": "Будут показаны все столбцы. Добавьте поля, чтобы выбрать конкретные.", + "addColumn": "Добавить столбец…", + "removeColumn": "Удалить столбец" + }, + "chartPreview": { + "title": "Предпросмотр диаграммы", + "noQuery": "Выберите набор данных, чтобы увидеть предпросмотр.", + "error": "Запрос предпросмотра завершился ошибкой." + }, + "chartTypeChip": { + "label": "Диаграмма:" + }, + "chartTypeModal": { + "title": "Выберите тип диаграммы", + "subtitle": "Выберите способ визуализации данных. Это можно изменить позже.", + "confirm": "Продолжить", + "swapTitle": "Изменить тип диаграммы", + "swapConfirm": "Применить" + }, + "saveVisualization": "Сохранить виджет", + "fieldSelect": { + "loading": "Загрузка полей…", + "choose": "Выберите поле…" + }, + "toast": { + "notReady": "Перед сохранением выберите набор данных и поле для разбивки." + }, + "breakdown": { + "title": "Разбивка по", + "time": "По времени", + "field": "Частые значения", + "interval": "Размер интервала", + "intervalAuto": "Автоматически", + "limit": "Сколько", + "limitPlaceholder": "По умолчанию (50)", + "splitHint": "Необязательно: по одной линии на каждое значение поля.", + "topValuesTable": "Tabla de valores principales" + }, + "editFilters": "Edit filters" + }, + "grid": { + "empty": "В этой панели пока нет виджетов.", + "missingVisualization": "Виджет недоступен", + "unknownVisualization": "Виджет" + }, + "widget": { + "renderError": "Не удалось отобразить этот виджет.", + "loading": "Загрузка данных…", + "queryError": "Не удалось загрузить данные виджета.", + "noData": "Нет данных за выбранный диапазон времени.", + "regionMapEmpty": "Нет точек с корректными широтой/долготой.", + "regionMapShapeHint": "SQL должен возвращать столбцы широты и долготы (или массив value [lat, lon, count]).", + "regionMapUnnamed": "(без названия)", + "regionMapValue": "значение: {{value}}", + "editAriaLabel": "Редактировать виджет", + "removeAriaLabel": "Удалить виджет", + "moveBack": "Переместить назад", + "moveForward": "Переместить вперёд", + "width": "Ширина", + "height": "Высота", + "widthSmall": "1 стлб", + "widthMedium": "2 стлб", + "widthLarge": "3 стлб", + "heightNormal": "Обычная", + "heightTall": "Высокая", + "incompleteSpec": "В этом виджете не хватает части вопроса.", + "count": "Conteo" + }, + "form": { + "createTitle": "Новая панель", + "renameTitle": "Редактировать панель", + "name": "Название", + "namePlaceholder": "напр. Обзор сети", + "description": "Описание", + "descriptionPlaceholder": "Необязательно", + "cancel": "Отмена", + "create": "Создать", + "save": "Сохранить" + }, + "confirm": { + "deleteTitle": "Удалить панель", + "delete": "Удалить панель «{{name}}»? Это действие нельзя отменить.", + "deleteWidgetsTitle": "Удалить виджеты", + "deleteWidgets_one": "Удалить этот виджет? Это действие нельзя отменить.", + "deleteWidgets_other": "Удалить виджетов: {{count}}? Это действие нельзя отменить.", + "dismissTitle": "Убрать панель", + "dismiss": "Удалить панель по умолчанию «{{name}}»? Позже вы сможете создать новую на её основе через «Создать» → «На основе существующего»." + }, + "page": { + "noSelection": "Выберите панель из списка или создайте новую, чтобы начать.", + "loading": "Загрузка виджетов…" + }, + "toast": { + "created": "Панель создана.", + "createFailed": "Не удалось создать панель.", + "updated": "Панель обновлена.", + "updateFailed": "Не удалось обновить панель.", + "deleted": "Панель удалена.", + "deleteFailed": "Не удалось удалить панель.", + "layoutSaved": "Макет сохранён.", + "layoutSaveFailed": "Не удалось сохранить макет.", + "visualizationCreated": "Виджет создан.", + "visualizationCreateFailed": "Не удалось создать виджет.", + "visualizationUpdated": "Виджет обновлён.", + "visualizationUpdateFailed": "Не удалось обновить виджет.", + "visualizationDeleted": "Виджет удалён.", + "visualizationDeleteFailed": "Не удалось удалить виджет.", + "filterCreated": "Фильтр создан.", + "filterUpdated": "Фильтр обновлён.", + "filterDeleted": "Фильтр удалён.", + "filterCreateFailed": "Не удалось создать фильтр.", + "filterUpdateFailed": "Не удалось обновить фильтр.", + "filterDeleteFailed": "Не удалось удалить фильтр.", + "filtersSaved": "Filters saved.", + "filtersSaveFailed": "Could not save filters." + }, + "newDashboard": { + "title": "Новая панель", + "subtitle": "Создайте пустую панель. Виджеты можно добавить после сохранения.", + "modeManual": "Создать вручную", + "modeAi": "С помощью ИИ", + "aiLocked": "Включите SOC-AI и настройте его, чтобы использовать эту функцию.", + "aiDescriptionLabel": "Что должна показывать эта панель?", + "aiDescriptionPlaceholder": "например, Неудачные входы по странам, последние 7 дней", + "aiCreate": "Создать с помощью ИИ", + "aiOpenerWithDetails": "Создай панель с названием «{{name}}», показывающую: {{description}}" + }, + "newVisualization": { + "title": "Новый виджет", + "subtitle": "Определите переиспользуемую диаграмму из SQL-запроса и конфигурации ECharts.", + "sqlQuery": "SQL-запрос", + "sqlQueryPlaceholder": "SELECT bucket, count(*) FROM logs GROUP BY bucket", + "sqlQueryHint": "Используйте плейсхолдеры timeFilter, from и to (в двойных фигурных скобках), чтобы выбор времени применялся при рендеринге.", + "config": "Конфигурация диаграммы (опция ECharts, JSON)", + "configHint": "Должен быть корректный JSON. Строки SQL доступны как `dataset.source` — свяжите серии через `encode`.", + "configError": "Некорректный JSON: {{error}}" + }, + "visualizationList": { + "title": "Виджеты", + "subtitle": "Доступно виджетов: {{count}}.", + "subtitleFiltered": "Показано {{shown}} из {{total}}.", + "create": "Создать", + "searchPlaceholder": "Поиск виджетов…", + "loading": "Загрузка виджетов…", + "empty": "Виджетов пока нет.", + "emptyFiltered": "Нет виджетов, соответствующих текущим фильтрам.", + "delete": "Удалить", + "deleteTitle": "Удалить виджет", + "confirmDelete": "Удалить виджет «{{name}}»? Это действие нельзя отменить.", + "filters": { + "search": "Поиск", + "chartType": "Тип диаграммы", + "allChartTypes": "Все типы диаграмм", + "source": "Источник", + "allSources": "Все источники", + "createdAt": "Создана", + "modifiedAt": "Изменена", + "createdRangeTitle": "Произвольный диапазон — Создание", + "modifiedRangeTitle": "Произвольный диапазон — Изменение", + "pickRange": "Выбрать диапазон", + "datePresets": { + "all": "Всё время", + "today": "Сегодня", + "last7": "За 7 дней", + "last30": "За 30 дней", + "lastYear": "За год", + "custom": "Произвольный" + }, + "clear": "Сбросить фильтры" + }, + "col": { + "name": "Название", + "chartType": "Тип диаграммы", + "source": "Источник", + "description": "Описание", + "created": "Создана", + "modified": "Изменена" + } + }, + "tabs": { + "dashboards": "Дашборды", + "visualizations": "Виджеты", + "newDashboard": "Новый дашборд", + "unsetDefault": "Убрать по умолчанию", + "options": "Параметры" + }, + "picker": { + "none": "Выбрать дашборд", + "search": "Поиск дашбордов…", + "new": "Новый дашборд", + "setDefault": "Сделать по умолчанию", + "empty": "Нет дашбордов" + }, + "empty": { + "title": "Дашбордов пока нет", + "body": "Создайте первый дашборд, чтобы видеть данные безопасности с одного взгляда.", + "cta": "Создать дашборд" + }, + "filters": { + "addTitle": "Добавить фильтр", + "editTitle": "Изменить фильтр", + "removeTitle": "Удалить фильтр", + "removeConfirm": "Удалить фильтр «{{label}}»? Это действие нельзя отменить.", + "remove": "Удалить", + "editAria": "Изменить фильтр", + "removeAria": "Удалить фильтр", + "saving": "Сохранение…", + "addChip": "Добавить фильтр", + "chooseValue": "Choose…", + "selected": "selected", + "loading": "Loading values…", + "searchPlaceholder": "Search values…", + "noValues": "No values available.", + "loadError": "Could not load values.", + "clear": "Clear", + "editorTitle": "Dashboard filters", + "editorHint": "Add dropdown chips that filter every widget on this dashboard.", + "emptyEditor": "No filter chips yet. Add one to get started.", + "cancel": "Cancel", + "save": "Save", + "field": { + "dataset": "Data set", + "field": "Field", + "chooseField": "Choose a field…", + "label": "Label", + "labelPlaceholder": "e.g. Host", + "placeholder": "Placeholder", + "placeholderPlaceholder": "e.g. Pick a host", + "multiple": "Multiple", + "searchable": "Searchable" + } + }, + "duplicate": { + "copyName": "{{name}} (копия)" + } }, - "sessions": { - "title": "Активные сеансы", - "description": "Устройства, на которых выполнен вход в вашу учётную запись.", - "loading": "Загрузка сеансов…", - "empty": "Нет активных сеансов.", - "thisDevice": "Это устройство", - "unknownIp": "Неизвестный IP", - "unknownDevice": "Неизвестное устройство", - "deviceLabel": "{{browser}} на {{os}}", - "signedIn": "Вход {{time}}", - "revoke": "Отозвать", - "revoking": "Отзыв…", - "signOutOthers": "Выйти из всех других сеансов", - "signingOut": "Выход…" + "settings": { + "title": "Настройки", + "license": "Лицензия", + "notifications": "Уведомления", + "connectionKey": "Ключ подключения", + "dataRetention": "Хранение данных", + "indices": "Индексы", + "theme": "Тема", + "apiKeys": "API-ключи", + "identityProviders": "Поставщики удостоверений", + "email": "Настройка эл. почты", + "dateFormat": "Формат даты", + "auditLogs": "Журнал аудита", + "about": "О системе", + "branding": "Брендинг", + "language": "Язык", + "socAi": "SOC-AI", + "supportAccess": "Доступ поддержки", + "threatwinds": "Интеграция ThreatWinds" + }, + "topbar": { + "theme": { + "light": "Светлая тема", + "dark": "Тёмная тема" + }, + "manageLicense": "Управление лицензией", + "profile": { + "profile": "Профиль", + "license": "Лицензия", + "logout": "Выйти" + } }, - "tfa": { - "title": "Двухфакторная аутентификация", - "description": "Добавьте дополнительный уровень защиты вашей учётной записи.", - "loading": "Загрузка…", - "methodTotp": "Приложение-аутентификатор", - "methodEmail": "Код по эл. почте", - "onTitle": "Двухфакторная аутентификация включена", - "method": "Метод: {{method}}", - "configured": "Настроено", - "disable": "Отключить", - "disableTitle": "Отключить двухфакторную аутентификацию", - "disableDescription": "Введите текущий пароль для подтверждения. После этого учётная запись будет защищена только паролем.", - "currentPasswordPlaceholder": "Текущий пароль", - "disableConfirm": "Отключить 2FA", - "disabling": "Отключение…", - "offTitle": "Двухфакторная аутентификация выключена", - "status": "Статус:", - "notConfigured": "Не настроено", - "enable": "Включить", - "chooseMethod": "Выберите метод", - "totpDesc": "Используйте Google Authenticator, 1Password и т. п. Рекомендуется.", - "emailDesc": "Получайте 6-значный код по эл. почте при входе.", - "noEmailHint": "Добавьте эл. почту в профиль, чтобы использовать метод по почте.", - "continue": "Продолжить", - "starting": "Запуск…", - "scanTitle": "Отсканируйте QR-код", - "scanDescription": "Отсканируйте его приложением-аутентификатором, затем введите показанный 6-значный код.", - "manualKey": "Или введите этот ключ вручную:", - "checkEmailTitle": "Проверьте почту", - "checkEmailDescription": "Мы отправили 6-значный код на {{email}}. Введите его ниже.", - "resend": "Отправить снова", - "verifyEnable": "Подтвердить и включить", - "verifying": "Проверка…" + "notifications": { + "title": "Уведомления", + "markAllRead": "Отметить все прочитанными", + "empty": "У вас нет уведомлений.", + "viewAll": "Показать все", + "markRead": "Отметить прочитанным", + "markUnread": "Отметить непрочитанным", + "delete": "Удалить", + "subtitle": "всего {{total}} · непрочитано {{unread}}", + "allCaughtUp": "Всё прочитано.", + "loadFailed": "Не удалось загрузить уведомления." }, - "actions": { - "cancel": "Отмена" + "pagination": { + "perPage": "На странице", + "pageOf": "Страница {{page}} из {{total}}", + "previous": "Назад", + "next": "Вперёд" }, - "toast": { - "profileUpdated": "Профиль обновлён", - "emailInUse": "Эта эл. почта уже используется", - "profileUpdateFailed": "Не удалось обновить профиль", - "passwordsNoMatch": "Пароли не совпадают", - "passwordTooShort": "Пароль должен содержать не менее 8 символов", - "passwordChanged": "Пароль изменён — другие сеансы завершены", - "currentPasswordWrong": "Неверный текущий пароль", - "passwordChangeFailed": "Не удалось изменить пароль", - "avatarTypeNotAllowed": "Недопустимый тип изображения (используйте PNG, JPEG, WEBP или GIF)", - "avatarTooLarge": "Изображение слишком большое (макс. 2 МБ)", - "avatarUpdated": "Аватар обновлён", - "avatarUploadFailed": "Не удалось загрузить аватар", - "avatarRemoved": "Аватар удалён", - "avatarRemoveFailed": "Не удалось удалить аватар", - "sessionsLoadFailed": "Не удалось загрузить сеансы", - "sessionRevoked": "Сеанс отозван", - "sessionRevokeFailed": "Не удалось отозвать сеанс", - "othersSignedOut": "Другие сеансы завершены", - "othersRevokeFailed": "Не удалось отозвать сеансы", - "tfaEmailCodeSent": "Мы отправили 6-значный код на вашу почту", - "tfaNewCodeSent": "Новый код отправлен", - "tfaWaitResend": "Подождите немного перед запросом нового кода", - "tfaResendFailed": "Не удалось отправить код повторно", - "tfaEnterCode": "Введите 6-значный код", - "tfaEnabled": "Двухфакторная аутентификация включена", - "tfaEnterPassword": "Введите текущий пароль", - "tfaDisabled": "Двухфакторная аутентификация отключена", - "tfaDisableFailed": "Не удалось отключить 2FA", - "tfaInvalidCode": "Неверный или просроченный код", - "tfaAlreadyEnabled": "2FA уже включена", - "tfaTooManyRequests": "Слишком много запросов; повторите чуть позже", - "tfaVerifyFailed": "Не удалось проверить код", - "genericError": "Что-то пошло не так", - "tfaMailUnavailable": "Второй фактор по почте требует почтового сервера. Настройте его в Настройки → Конфигурация почты." - } - }, - "home": { - "hero": { - "title": "Что вы хотите узнать из ваших данных безопасности?", - "placeholder": "Изучите Scattered Spider, применимо ли это к нам?, атаковали ли нас когда-нибудь?, создайте правило обнаружения и поддерживайте его в актуальном состоянии.", - "send": "Отправить", - "suggestions": { - "threatHunt": "Поиск угроз", - "observableTriage": "Триаж индикаторов", - "writeRule": "Написать правило", - "systemStatus": "Текущее состояние системы" - } + "license": { + "title": "Лицензия", + "subtitle": "Ваша редакция, возможности и файл лицензии.", + "loading": "Загрузка лицензии…", + "loadError": "Не удалось загрузить информацию о лицензии.", + "statusLabel": "Статус", + "status": { + "community": "Community", + "active": "Активна", + "expiring": "Скоро истекает", + "expired": "Истекла" + }, + "edition": "Редакция", + "enterprise": "Enterprise", + "community": "Community", + "editionLine": "Редакция {{edition}}", + "datasourceLimit": "Лимит источников данных", + "unlimited": "Без ограничений", + "mssp": "MSSP / мультиарендность", + "enabled": "Включено", + "licenseType": "Тип лицензии", + "instanceId": "ID экземпляра", + "enterpriseUnlocked": "Функции Enterprise разблокированы", + "validUntil": "Действует до", + "noExpiry": "Без срока действия", + "timeRemaining": "Осталось времени", + "expiredAgo": "Истекла {{days}} дн. назад", + "daysShort": "{{days}} дн.", + "msspShort": "MSSP", + "communityEdition": "Редакция Community", + "communityBlurb": "Бесплатная и с открытым исходным кодом. Загрузите лицензию Enterprise ниже, чтобы разблокировать мультиарендность, SSO, увеличенные лимиты источников данных и расширенное соответствие.", + "upgrade": "Перейти на Enterprise", + "uploadTitle": "Загрузить лицензию", + "uploadBlurb": "Установите или замените подписанный файл LICENSE. Сервер проверяет подпись и срок действия перед применением. Только для администраторов.", + "installLicense": "Установить лицензию", + "chooseFile": "Выбрать файл", + "noFileSelected": "Файл не выбран", + "toast": { + "installed": "Лицензия установлена — редакция {{edition}}.", + "adminRequired": "Для загрузки лицензии нужны права администратора.", + "invalid": "Недействительный или просроченный файл лицензии.", + "installFailed": "Не удалось установить лицензию." + }, + "ingestLimit": "Объём приёма", + "notMetered": "Без учёта", + "gbPerMonth": "{{gb}} ГБ/месяц" + }, + "audit": { + "title": "Журнал аудита", + "subtitle": "Запись всех действий, связанных с безопасностью.", + "totalEntries": "всего записей: {{total}}.", + "loadError": "Не удалось загрузить журнал аудита", + "stats": { + "totalEntries": "Всего записей", + "acrossAllTime": "За всё время", + "successRate": "Доля успешных", + "failuresOnPage_one": "{{count}} сбой на этой странице", + "failuresOnPage_few": "{{count}} сбоя на этой странице", + "failuresOnPage_many": "{{count}} сбоев на этой странице", + "failuresOnPage_other": "{{count}} сбоев на этой странице", + "topAction": "Частое действие", + "onPage": "{{count}} на этой странице", + "uniqueActors": "Уникальных пользователей", + "includingSystem": "Включая систему" + }, + "filters": { + "title": "Фильтры", + "clear": "Очистить", + "last24h": "За 24 ч", + "failuresOnly": "Только сбои", + "authEvents": "События входа", + "actionPrefix": "Префикс действия", + "actionPlaceholder": "напр. auth., user.update", + "status": "Статус", + "any": "Любой", + "resourceType": "Тип ресурса", + "resourceTypePlaceholder": "user, alert…", + "resourceId": "ID ресурса", + "user": "Пользователь", + "userPlaceholder": "логин…" + }, + "statusValue": { + "success": "Успех", + "failure": "Сбой" + }, + "table": { + "timestamp": "Время", + "actor": "Субъект", + "action": "Действие", + "resource": "Ресурс", + "status": "Статус", + "ip": "IP", + "loading": "Загрузка…", + "emptyTitle": "Нет записей аудита по этим фильтрам.", + "emptyHint": "Попробуйте очистить фильтры или расширить диапазон дат.", + "system": "система", + "view": "Открыть" + }, + "drawer": { + "entry": "запись №{{id}}", + "overview": "Обзор", + "raw": "Сырой JSON", + "error": "Ошибка", + "actor": "Субъект", + "resource": "Ресурс", + "ip": "IP", + "userAgent": "User agent", + "session": "Сеанс", + "metadata": "Метаданные", + "copy": "Копировать", + "copied": "Скопировано", + "copyJson": "Копировать JSON" + } }, - "kpis": { - "alerts24h": "Оповещения (24 ч)", - "openIncidents": "Открытые инциденты", - "openIncidentsSub": "сейчас открыты", - "highSeverity24h": "Высокая важность (24 ч)", - "highSeveritySub": "из {{n}} оповещений", - "activePlaybooks": "Активные плейбуки", - "activePlaybooksSub": "включены" + "team": { + "title": "Команда", + "subtitle": "Управление пользователями и их ролями.", + "tabs": { + "members": "Участники", + "roles": "Роли и разрешения" + }, + "toast": { + "rolesLoadFailed": "Не удалось загрузить роли", + "userLoadFailed": "Не удалось загрузить пользователя", + "rolesUpdated": "Роли обновлены", + "userReactivated": "Пользователь повторно активирован", + "userDeactivated": "Пользователь деактивирован", + "tfaReset": "Двухфакторная аутентификация сброшена", + "invitationSent": "Приглашение отправлено", + "loginOrEmailInUse": "Этот логин или эл. почта уже используются", + "invalidRequest": "Неверный запрос", + "noPermission": "У вас нет прав для этого действия", + "userNotFound": "Пользователь не найден", + "operationFailed": "Операция не выполнена", + "emailInUse": "Эта почта уже используется", + "roleCreated": "Роль создана", + "roleUpdated": "Роль обновлена", + "roleDeleted": "Роль удалена", + "roleNameInUse": "Роль с таким идентификатором уже существует", + "roleImmutable": "Системные роли нельзя изменять", + "permissionsLoadFailed": "Не удалось загрузить разрешения", + "localUserCreated": "Локальный пользователь создан" + }, + "members": { + "searchPlaceholder": "Поиск по имени или почте…", + "invite": "Пригласить пользователя", + "colUser": "Пользователь", + "colRoles": "Роли", + "col2fa": "2FA", + "colStatus": "Статус", + "loading": "Загрузка пользователей…", + "loadFailed": "Не удалось загрузить пользователей.", + "retry": "Повторить", + "noSearchMatch": "Нет пользователей по вашему запросу.", + "none": "Пользователей пока нет.", + "noRole": "нет", + "on": "Вкл", + "off": "Выкл", + "countLabel_one": "{{count}} пользователь · страница {{page}} из {{pages}}", + "countLabel_few": "{{count}} пользователя · страница {{page}} из {{pages}}", + "countLabel_many": "{{count}} пользователей · страница {{page}} из {{pages}}", + "countLabel_other": "{{count}} пользователей · страница {{page}} из {{pages}}", + "federated": "SSO" + }, + "status": { + "inactive": "Неактивен", + "pendingPassword": "Ожидает пароль", + "active": "Активен", + "pending": "Приглашение отправлено", + "suspended": "Заблокирован" + }, + "drawer": { + "createdBy": "создан {{actor}}", + "loading": "Загрузка…", + "profileTitle": "Профиль", + "profileSubtitle": "Эти данные может изменить только сам пользователь — в своём профиле.", + "name": "Имя", + "username": "Имя пользователя", + "email": "Эл. почта", + "language": "Язык", + "accountTitle": "Учётная запись", + "status": "Статус", + "statusActive": "Активен", + "statusInactive": "Неактивен", + "tfa": "2FA", + "tfaEnabled": "Включена", + "tfaNotConfigured": "Не настроено", + "resetTfa": "Сбросить", + "resetTfaHint": "Отключить 2FA этого пользователя, чтобы он заново настроил её при следующем входе", + "resetTfaConfirmTitle": "Сбросить двухфакторную аутентификацию?", + "resetTfaConfirmBody": "Это отключит 2FA для {{name}}. Пользователь войдёт только по паролю и сможет снова настроить её в своём профиле.", + "resetTfaConfirm": "Сбросить 2FA", + "pendingPasswordNote": "Всё ещё использует временный пароль (приглашение не завершено).", + "lastModified": "Изменён {{time}}", + "rolesTitle": "Роли", + "rolesSubtitle": "Роли дают разрешения на модули. Пользователь может иметь несколько ролей.", + "noRoleWarning": "Роль не назначена — у пользователя не будет доступа к модулям.", + "deactivate": "Деактивировать", + "reactivate": "Активировать снова", + "waitingInvite": "Ожидание принятия приглашения пользователем.", + "cancel": "Отмена", + "saving": "Сохранение…", + "saveRoles": "Сохранить роли", + "created": "создан {{time}}", + "pendingNote": "Приглашение ещё не принято.", + "federatedNote": "Вход через поставщика удостоверений." + }, + "invite": { + "title": "Пригласить пользователя", + "description": "Учётная запись создаётся неактивной. Пользователь получит письмо, чтобы задать пароль и активировать её.", + "username": "Имя пользователя", + "usernameHint": "Не менее 3 символов.", + "email": "Эл. почта", + "firstName": "Имя", + "lastName": "Фамилия", + "roles": "Роли", + "cancel": "Отмена", + "sending": "Отправка…", + "send": "Отправить приглашение", + "name": "Имя", + "emailHint": "С этого адреса пользователь будет входить.", + "localDescription": "Учётная запись создаётся с паролем и немедленно активируется. Письмо не отправляется.", + "modeInvite": "Пригласить пользователя", + "modeLocal": "Создать локального пользователя", + "passwordLabel": "Пароль", + "passwordPlaceholder": "Задайте надёжный пароль", + "localUserNote": "Этот пользователь не получит письмо и будет автоматически активирован.", + "createLocal": "Создать пользователя", + "passwordRules": { + "length": "Не менее 8 символов", + "case": "Хотя бы одна заглавная и одна строчная буква", + "special": "Хотя бы один специальный символ" + }, + "emailInvalid": "Введите корректный адрес электронной почты" + }, + "rolePicker": { + "none": "Нет доступных ролей." + }, + "roles": { + "loading": "Загрузка ролей…", + "loadFailed": "Не удалось загрузить разрешения ролей.", + "readonlyNote": "Роли и их разрешения определяются системой и доступны только для чтения. Назначайте их пользователям на вкладке «Участники».", + "permissionsCount_one": "{{count}} разрешение", + "permissionsCount_few": "{{count}} разрешения", + "permissionsCount_many": "{{count}} разрешений", + "permissionsCount_other": "{{count}} разрешений", + "modulesCount_one": "{{count}} модуль", + "modulesCount_few": "{{count}} модуля", + "modulesCount_many": "{{count}} модулей", + "modulesCount_other": "{{count}} модулей", + "matrixTitle": "Матрица разрешений", + "matrixSubtitle": "Что может делать каждая роль, по модулям.", + "permission": "Разрешение", + "systemNote": "Системные роли поставляются с платформой и не редактируются. Созданные вами роли принадлежат этому арендатору.", + "newRole": "Новая роль", + "edit": "Изменить", + "delete": "Удалить", + "systemBadge": "Системная", + "createTitle": "Новая роль", + "editTitle": "Изменение роли", + "editorSubtitle": "Выберите, что разрешено этой роли. У пользователя может быть несколько ролей.", + "nameLabel": "Идентификатор", + "nameHint": "Используется в коде и API. Например, ROLE_AUDITOR.", + "displayNameLabel": "Отображаемое имя", + "descriptionLabel": "Описание", + "permissionsLabel": "Разрешения", + "selectedCount": "выбрано: {{count}}", + "toggleAll": "все", + "loadingPermissions": "Загрузка разрешений…", + "save": "Сохранить роль", + "deleteConfirmTitle": "Удалить эту роль?", + "deleteConfirmBody": "{{name}} будет удалена. Те, у кого есть только эта роль, потеряют доступ к модулям." + }, + "langDefault": "Системный по умолчанию", + "relative": { + "justNow": "только что", + "minutesAgo": "{{count}} мин. назад", + "hoursAgo": "{{count}} ч. назад", + "daysAgo": "{{count}} дн. назад" + }, + "roleNames": { + "ROLE_ADMIN": "Администратор", + "ROLE_USER": "Пользователь" + }, + "roleDescriptions": { + "ROLE_ADMIN": "Полный доступ ко всем ресурсам", + "ROLE_USER": "Стандартный пользователь с доступом на чтение на уровне модулей" + }, + "actions": { + "read": "Чтение", + "write": "Запись", + "delete": "Удаление" + }, + "resources": { + "adaudit": "Аудит AD", + "alerts": "Оповещения", + "audit": "Журнал аудита", + "compliance": "Соответствие", + "config": "Конфигурация", + "dashboards": "Панели", + "datasources": "Datasources", + "eventprocessing": "Обработка событий", + "idp": "Поставщики идентификации", + "incidents": "Инциденты", + "integrations": "Интеграции", + "loganalyzer": "Анализатор логов", + "opensearch": "OpenSearch", + "roles": "Роли", + "soar": "SOAR", + "users": "Пользователи", + "notifications": "Уведомления", + "socai": "SOC AI", + "tenant": "Арендаторы", + "threatintel": "Threat Intelligence" + } }, - "datasources": { - "title": "Источники данных", - "viewAll": "Показать все", - "ofTotal": "из {{n}}", - "datasources": "источников данных", - "sendingData": "отправляют данные", - "totalEvents": "Всего событий", - "noData": "Нет данных о приёме в этом интервале" + "apiKeys": { + "title": "API-ключи", + "subtitle": "Программные токены доступа к API UTMStack.", + "new": "Новый API-ключ", + "searchPlaceholder": "Поиск по имени или разрешённому IP…", + "refresh": "Обновить", + "loading": "Загрузка API-ключей…", + "loadFailed": "Не удалось загрузить API-ключи.", + "retry": "Повторить", + "noSearchMatch": "Нет API-ключей по вашему запросу.", + "empty": "API-ключей пока нет. Создайте первый.", + "anyIp": "Любой IP", + "never": "Никогда", + "count_one": "{{count}} ключ · страница {{page}} из {{pages}}", + "count_few": "{{count}} ключа · страница {{page}} из {{pages}}", + "count_many": "{{count}} ключей · страница {{page}} из {{pages}}", + "count_other": "{{count}} ключей · страница {{page}} из {{pages}}", + "enterprise": { + "title": "API-ключи — функция Enterprise", + "body": "Создавайте, ограничивайте и обновляйте API-ключи для программного доступа к API UTMStack. Эта возможность доступна в редакции Enterprise.", + "upgrade": "Перейти на Enterprise", + "manageLicense": "Управление лицензией" + }, + "col": { + "name": "Имя", + "allowedIps": "Разрешённые IP", + "created": "Создан", + "lastRotated": "Последняя ротация", + "expires": "Истекает", + "status": "Статус", + "actions": "Действия" + }, + "status": { + "active": "Активен", + "expiring": "Истекает", + "expired": "Истёк" + }, + "action": { + "rotate": "Ротация", + "edit": "Изменить", + "delete": "Удалить" + }, + "dialog": { + "editTitle": "Изменить API-ключ", + "newTitle": "Новый API-ключ", + "name": "Имя", + "namePlaceholder": "ci-pipeline", + "allowedIps": "Разрешённые IP", + "allowedIpsHint": "Через запятую. Оставьте пустым, чтобы разрешить любой IP.", + "expires": "Истекает", + "expiresHint": "Оставьте пустым, чтобы ключ не истекал.", + "secretNote": "Секретный токен показывается один раз, сразу после создания. Скопируйте его — позже его нельзя получить (только ротация).", + "cancel": "Отмена", + "saving": "Сохранение…", + "saveChanges": "Сохранить изменения", + "createKey": "Создать ключ" + }, + "confirm": { + "deleteTitle": "Удалить API-ключ", + "rotateTitle": "Ротация API-ключа", + "deleteBody": "Удалить {{name}}? Любой клиент, использующий его, немедленно потеряет доступ. Действие необратимо.", + "rotateBody": "Выполнить ротацию {{name}}? Будет выдан новый секрет, а текущий немедленно перестанет работать. Новый токен показывается один раз.", + "cancel": "Отмена", + "working": "Выполнение…", + "delete": "Удалить", + "rotate": "Ротация" + }, + "reveal": { + "title": "API-ключ создан", + "note": "Скопируйте этот секрет сейчас — для {{name}}. Он больше не будет показан. Если потеряете — выполните ротацию ключа.", + "copied": "Скопировано", + "copy": "Копировать", + "done": "Готово" + }, + "toast": { + "updated": "API-ключ обновлён", + "secretIssueFailed": "Ключ создан, но секрет не удалось выдать. Используйте «Ротация», чтобы получить его.", + "deleted": "API-ключ удалён" + }, + "error": { + "nameTaken": "API-ключ с таким именем уже существует", + "enterpriseRequired": "API-ключи требуют редакцию Enterprise", + "notFound": "API-ключ не найден", + "invalidRequest": "Неверный запрос", + "failed": "Операция не выполнена" + } }, - "span": { - "recent": "недавний период", - "days_one": "последний {{count}} день", - "days_few": "последние {{count}} дня", - "days_many": "последние {{count}} дней", - "days_other": "последние {{count}} дней", - "hours": "последние {{n}} ч" + "idp": { + "title": "Поставщики удостоверений", + "subtitle": "Единый вход SAML 2.0 для вашей организации.", + "add": "Добавить поставщика", + "enterprise": { + "title": "SSO — функция Enterprise", + "body": "Подключите поставщика удостоверений SAML 2.0 (Entra ID, Okta, Google Workspace…), чтобы команда входила через ваш IdP. Единый вход доступен в редакции Enterprise.", + "upgrade": "Перейти на Enterprise" + }, + "loading": "Загрузка поставщиков удостоверений…", + "loadFailed": "Не удалось загрузить поставщиков удостоверений.", + "retry": "Повторить", + "empty": { + "title": "Поставщики удостоверений не настроены", + "body": "Добавьте поставщика SAML 2.0, чтобы команда входила через корпоративный IdP." + }, + "card": { + "enable": "Включить", + "disable": "Отключить", + "active": "Активен", + "disabled": "Отключён", + "metadataUrl": "URL метаданных", + "spEntityId": "SP Entity ID", + "spAcsUrl": "SP ACS URL", + "loginUrl": "URL входа", + "copy": "Копировать", + "edit": "Изменить", + "delete": "Удалить", + "jit": "Provisioning", + "jitOn": "creates accounts on first sign-in", + "sync": "Roles", + "syncOn": "re-applied on every sign-in" + }, + "form": { + "addTitle": "Добавить поставщика удостоверений", + "editTitle": "Изменить поставщика удостоверений", + "name": "Имя", + "nameHint": "Уникальное. Используется в URL SSO.", + "providerType": "Тип поставщика", + "providerTypeHint": "Метка, напр. azure, okta, google.", + "metadataUrl": "URL метаданных IdP", + "spEntityId": "SP Entity ID", + "spAcsUrl": "SP ACS URL", + "certificate": "Сертификат SP (PEM)", + "privateKey": "Приватный ключ SP (PEM)", + "privateKeyHintEdit": "Оставьте пустым, чтобы сохранить текущий ключ.", + "privateKeyHintCreate": "Обязательно. Хранится в зашифрованном виде; больше не показывается.", + "privateKeyUnchanged": "•••••••• (без изменений)", + "active": "Активен (показывать на странице входа)", + "cancel": "Отмена", + "saving": "Сохранение…", + "save": "Сохранить изменения", + "create": "Создать поставщика", + "issuer": "Issuer URL", + "issuerHint": "Discovery runs against this; the provider must serve /.well-known/openid-configuration under it.", + "clientId": "Client ID", + "redirectUrl": "Redirect URL", + "redirectUrlHint": "Register this exact URL with the provider.", + "host": "Host", + "port": "Port", + "startTls": "TLS", + "startTlsOn": "Use StartTLS", + "bindDn": "Bind DN", + "bindDnHint": "A service account that may search the directory.", + "baseDn": "Base DN", + "userFilter": "User filter", + "userFilterHint": "Must contain %s, where the address typed at login is placed.", + "emailAttribute": "Email attribute", + "nameAttribute": "Name attribute", + "groupAttribute": "Group attribute", + "provisioning": "Accounts and roles", + "provisioningHint": "What happens when someone the directory vouches for signs in.", + "jit": "Create the account on first sign-in", + "defaultRole": "Default role", + "defaultRoleHint": "Given when no group matches. Without one, an unmatched sign-in is refused.", + "noDefaultRole": "None", + "groupsAttribute": "Groups attribute", + "groupsAttributeHint": "Where the provider puts group membership.", + "syncRoles": "Re-apply roles on every sign-in", + "syncRolesHint": "Roles not in the mapping are removed, so a change in the directory reaches here. Without this, a demotion never arrives.", + "mappings": "Group to role", + "mappingsHint": "A directory group on the left, the role it grants on the right.", + "addMapping": "Add", + "noMappings": "No mappings. Everyone gets the default role.", + "groupPlaceholder": "SOC Analysts", + "pickRole": "Pick a role", + "secret.saml": "SP private key", + "secret.oidc": "Client secret", + "secret.ldap": "Bind password", + "secretHintCreate": "Stored encrypted and never shown again.", + "secretHintEdit": "Leave blank to keep the stored one.", + "secretUnchanged": "без изменений", + "errors": { + "required": "Это поле обязательно.", + "url": "Должно быть корректным URL http(s).", + "httpsUrl": "Должно быть корректным URL https.", + "hostname": "Введите хост или IP без схемы (например, ldap.example.com).", + "port": "Порт должен быть целым числом от 0 до 65535.", + "pemCertificate": "Не похоже на сертификат PEM (нет -----BEGIN/END CERTIFICATE-----).", + "pemKey": "Не похоже на закрытый ключ PEM (нет -----BEGIN/END PRIVATE KEY-----).", + "userFilterPlaceholder": "Фильтр должен содержать %s, куда подставляется адрес входа.", + "userFilterUnbalanced": "Круглые скобки не сбалансированы — поиск ничего не вернёт.", + "nameFormat": "Используйте буквы, цифры, точки, дефисы или подчёркивания (макс. 64). Это имя входит в URL SSO, пробелы недопустимы.", + "redirectUrl": "Должно быть корректным URL https либо http-loopback URL (localhost / 127.0.0.1 / [::1]).", + "entityId": "Должно быть корректным URI, например, https://utmstack.example.com/sp." + } + }, + "delete": { + "title": "Удалить поставщика удостоверений", + "body": "Удалить {{name}}? Пользователи больше не смогут входить через него. Действие необратимо.", + "cancel": "Отмена", + "deleting": "Удаление…", + "confirm": "Удалить" + }, + "toast": { + "enabled": "Поставщик включён", + "disabled": "Поставщик отключён", + "created": "Поставщик удостоверений создан", + "updated": "Поставщик удостоверений обновлён", + "deleted": "Поставщик удостоверений удалён", + "paidPlan": "SAML SSO требует платный план", + "enterpriseRequired": "SSO требует редакцию Enterprise", + "notFound": "Поставщик удостоверений не найден", + "invalid": "Неверная конфигурация", + "failed": "Операция не выполнена" + }, + "providerType": { + "saml": "SAML 2.0", + "oidc": "OpenID Connect", + "ldap": "LDAP / Active Directory", + "comingSoon": "пока недоступно" + } }, - "mitre": { - "title": "Топ техник MITRE ATT&CK", - "explore": "Изучить", - "empty": "Пока нет оповещений с указанной техникой" + "userAuditor": { + "title": "Аудит пользователей", + "subtitle": "Учётные записи Active Directory, замеченные в журналах безопасности Windows — обнаружены из событий создания, входа и удаления.", + "export": "Экспорт", + "accountsChip": "{{count}} учётных записей", + "overview": { + "title": "Инвентарь учётных записей", + "active": "активные", + "disabled": "отключённые", + "deleted": "удалённые", + "seen24h": "{{count}} замечено за последние 24 часа", + "byDomain": "По домену", + "grouped": "{{count}} сгруппировано", + "unassigned": "{{count}} без группы" + }, + "views": { + "all": "Все учётные записи", + "windows": "Windows", + "linux": "Linux", + "active": "Активные", + "disabled": "Отключённые", + "deleted": "Удалённые", + "service": "Служебные учётные записи", + "stale": "Устаревшие (30+ дн.)", + "o365": "O365", + "azure": "Azure", + "gcp": "GCP", + "aws": "AWS" + }, + "searchPlaceholder": "Поиск по имени учётной записи или SID…", + "allTenants": "Все арендаторы", + "filters": { + "add": "Добавить фильтр", + "clearAll": "Очистить всё", + "filterValues": "Фильтровать значения…", + "loadingValues": "Загрузка значений…", + "noValues": "Значения не найдены.", + "pickValue": "Выберите значение, чтобы добавить фильтр.", + "empty": "(пусто)", + "cancel": "Отмена", + "addBtn": "Добавить" + }, + "filterFields": { + "status": "Статус жизненного цикла" + }, + "ops": { + "is": "равно" + }, + "refresh": "Обновить", + "layout": { + "list": "Список", + "cards": "Карточки" + }, + "list": { + "account": "Учётная запись", + "identity": "Идентификатор", + "sid": "SID", + "status": "Статус", + "lastLogon": "Последний вход", + "lastSeen": "Последняя активность", + "tenant": "Арендатор", + "accountId": "ID учетной записи", + "identityGroup": "Группа идентичности" + }, + "status": { + "active": "Активна", + "disabled": "Отключена", + "deleted": "Удалена" + }, + "badge": { + "service": "служебная", + "stale": "устаревшая" + }, + "empty": "Нет учётных записей для этого представления.", + "loadError": "Не удалось загрузить учётные записи AD.", + "retry": "Повторить", + "card": { + "lastLogon": "Последний вход" + }, + "pageInfo": "{{from}}–{{to}} из {{count}}", + "drawer": { + "tenantInline": "арендатор {{id}}", + "serviceAccount": "служебная учётная запись", + "stale": "устарела 30+ дн.", + "viewInLogs": "Открыть события в обозревателе логов", + "copySid": "Копировать SID", + "copyUid": "Копировать идентификатор", + "copied": "Скопировано", + "identity": "Идентификация", + "accountName": "Имя учётной записи", + "domain": "Домен", + "hostname": "Имя хоста", + "sid": "SID", + "uidNumber": "UID", + "machineId": "ID машины", + "tenant": "Арендатор", + "adStatus": "Статус AD", + "enabled": "Включена", + "disabled": "Отключена", + "lifecycle": "Жизненный цикл", + "created": "Учётная запись создана", + "lastLogon": "Последний вход", + "lastSeen": "Последняя активность в логах", + "deleted": "Учётная запись удалена", + "noLifecycle": "Нет записей о событиях жизненного цикла.", + "aliasGroup": "Группа идентичности", + "alias": { + "add": "Добавить группу идентичности", + "search": "Поиск групп…", + "none": "Групп пока нет", + "new": "Новая группа", + "unassign": "Убрать из группы", + "unassigned": "Без группы", + "newPlaceholder": "Название новой группы (2–64 символа)", + "createAndAssign": "Создать и назначить", + "nameTooShort": "Название должно быть от 2 до 64 символов", + "updated": "Группа идентичности обновлена", + "updateFailed": "Не удалось обновить группу идентичности" + } + }, + "relative": { + "justNow": "только что", + "minutesAgo": "{{count}} мин. назад", + "hoursAgo": "{{count}} ч. назад", + "daysAgo": "{{count}} дн. назад" + }, + "none": "—", + "allIdentities": "Все группы идентичности", + "noneIdentity": "Без группы идентичности" + }, + "connectionKey": { + "title": "Ключ подключения", + "subtitle1": "Ключ, который агенты предъявляют при регистрации на этом экземпляре.", + "subtitleEmphasis": "Используется только для установки агентов", + "subtitle2": "— не для коллекторов, интеграций или API. Управляется agent-manager.", + "status": { + "label": "Статус", + "loading": "Загрузка…", + "unavailable": "Agent-manager недоступен", + "active": "Активен", + "unavailableHint": "Не удалось связаться с agent-manager для чтения ключа.", + "activeHint": "Агенты могут регистрироваться по этому ключу." + }, + "token": { + "title": "Ключ подключения", + "subtitle": "Относитесь к этому значению как к учётным данным. Ротация выдаёт новый ключ для будущих установок агентов — уже зарегистрированные агенты продолжают работать.", + "loadFailedTitle": "Не удалось загрузить ключ подключения", + "unavailableTitle": "Ключ подключения недоступен", + "loadFailedHint": "Ключом управляет agent-manager, который не ответил. Повторите попытку через мгновение.", + "retry": "Повторить", + "show": "Показать ключ", + "hide": "Скрыть ключ", + "copy": "Копировать", + "copied": "Скопировано", + "regenerate": "Перегенерировать ключ подключения", + "confirmTitle": "Перегенерировать ключ?", + "confirmBody": "Новым установкам агентов потребуется новый ключ. Уже зарегистрированные агенты продолжат работать. Отменить нельзя.", + "regenerating": "Перегенерация…", + "confirmYes": "Да, перегенерировать", + "cancel": "Отмена" + }, + "security": { + "title": "Рекомендации по безопасности", + "subtitle": "Лучшие практики защиты этих учётных данных.", + "rotateTitle": "Ротация каждые 90 дней", + "rotateBody": "Запланируйте регулярную ротацию. UTMStack может отправить вам напоминание по эл. почте, когда ключу больше 90 дней.", + "rotateAction": "Настроить напоминание", + "secretTitle": "Храните как секрет", + "secretBody": "Не добавляйте в систему контроля версий. Используйте менеджер секретов (Vault, AWS SM и т. п.) и подставляйте при установке.", + "auditTitle": "Аудит, кто его получил", + "auditBody": "Каждое получение и ротация фиксируются в журнале аудита приложения.", + "auditAction": "Открыть журнал аудита" + }, + "toast": { + "loadFailed": "Не удалось загрузить ключ подключения", + "rotated": "Ключ подключения ротирован", + "rotateFailed": "Не удалось ротировать ключ подключения", + "copyFailed": "Не удалось скопировать" + } }, - "assets": { - "title": "Наиболее атакуемые активы", - "viewAll": "Показать все", - "asset": "Актив", - "alerts": "Оповещения", - "empty": "Нет атакуемых активов в недавних оповещениях" + "dataRetention": { + "title": "Хранение данных", + "subtitle": "How long each dataset is kept, and when its records stop costing local disk.", + "loading": "Загрузка…", + "loadFailed": "Could not read the store.", + "retry": "Повторить", + "datasets": { + "logs": "Logs", + "alerts": "Alerts", + "statistics": "Ingestion statistics" + }, + "holding": "{{documents}} records · {{size}}", + "since": "since {{date}}", + "diskUsed": "Disk {{pct}}% used", + "keep": "Delete after", + "keepHint": "A record is deleted this many days after it happened, wherever it is stored by then.", + "cold": "Move to cold storage after", + "coldHint": "Older records move to object storage and stay queryable. 0 keeps everything on local disk.", + "coldUnavailable": "Set up cold storage below to move older records off local disk.", + "coldBeforeDelete": "Records have to move before they are deleted: use fewer days than the lifetime, or 0.", + "tieredNote": "This dataset moves records to cold storage. Going back to local-only needs the table rebuilt, so it cannot be turned off here.", + "days": "дней", + "save": "Сохранить", + "saving": "Сохранение…", + "toast": { + "saved": "Retention saved", + "noPermission": "You do not have permission to change retention", + "saveFailed": "Could not save the retention" + }, + "coldStorage": { + "title": "Cold storage", + "hint": "An object store the event store treats as a second, slower disk. Older records move there and are still queried from the same place — it is not an archive and nothing has to be restored.", + "active": "In use", + "inactive": "Not set up", + "writtenNotReady": "The bucket is configured but the store has not picked it up. Check that the deployment shares the store's configuration directory.", + "endpoint": "Bucket URL", + "accessKey": "Access key", + "secretKey": "Secret key", + "bucketLocked": "The credentials can be changed at any time. The bucket cannot, once records live in it: the parts already moved carry it.", + "enable": "Enable cold storage", + "update": "Update credentials", + "toast": { + "saved": "Cold storage configured", + "failed": "Could not configure cold storage" + }, + "kind": "Тип", + "kind_s3": "Объектное хранилище, совместимое с S3", + "kind_local": "Локальная папка или NFS", + "kind_azure": "Azure Blob Storage", + "accountUrl": "URL учётной записи хранилища", + "container": "Контейнер", + "accountName": "Имя учётной записи", + "accountKey": "Ключ учётной записи", + "useRole": "Использовать IAM-роль сервера вместо ключей", + "s3Hint": "Работает с AWS S3 и любым S3-совместимым хранилищем: MinIO, Ceph, Wasabi, Cloudflare R2 или Google Cloud Storage (endpoint https://storage.googleapis.com// с HMAC-ключами).", + "localHint": "Записи переносятся в папку, смонтированную как /mnt/utmstack-cold внутри хранилища событий: обычный каталог в папке данных или NFS-ресурс, смонтированный на хосте поверх <каталог данных>/clickhouse/cold до запуска стека. Учётные данные не нужны.", + "changeWarning": "Records already moved to the current destination are not migrated. They stay there and stop being readable from here until the old destination is copied across by hand." + }, + "forbidden": { + "title": "Эта страница принадлежит платформе", + "body": "Хранение относится к таблицам, общим для всех тенантов: читать и менять его может только администратор платформы." + } }, - "compliance": { - "title": "Оценка соответствия", - "reports": "Отчёты", - "empty": "Отчёты о соответствии ещё не созданы" + "about": { + "title": "Об этом экземпляре", + "subtitle": "Версия, лицензия и состояние системы этого развёртывания UTMStack.", + "loading": "Загрузка информации об экземпляре…", + "edition": { + "enterprise": "Enterprise", + "community": "Community" + }, + "fields": { + "hostname": "Сервер", + "instanceId": "ID экземпляра", + "noInstanceMeta": "Метаданные экземпляра недоступны." + }, + "license": { + "title": "Лицензия", + "enterpriseMssp": "Enterprise · MSSP", + "datasources": "Datasources", + "communityLimited": "Лимит Community", + "unlimited": "Без ограничений", + "expires": "Истекает", + "managedNote": "Редакция, лимиты datasources и загрузка лицензии управляются на странице «Лицензия».", + "view": "Открыть лицензию", + "ingest": "Объём приёма", + "notMetered": "Без учёта", + "gbPerMonth": "{{gb}} ГБ/месяц" + }, + "services": { + "backend": { + "name": "Backend API", + "desc": "REST-шлюз, аутентификация и оркестрация модулей." + }, + "opensearch": { + "name": "OpenSearch", + "desc": "Хранилище логов и событий.", + "detail": "{{nodes}} узлов · {{shards}} шардов" + }, + "unreachable": "Недоступно" + }, + "status": { + "up": "В норме", + "degraded": "Снижено", + "down": "Недоступно", + "unknown": "Неизвестно" + }, + "health": { + "title": "Состояние системы", + "allHealthy": "Все сервисы в норме. Обновите для повторной проверки.", + "issues_one": "{{count}} сервис требует внимания.", + "issues_few": "{{count}} сервиса требуют внимания.", + "issues_many": "{{count}} сервисов требуют внимания.", + "issues_other": "{{count}} сервисов требуют внимания.", + "refresh": "Обновить" + }, + "usage": { + "title": "Источники данных", + "subtitle": "Источники данных, настроенные в этой установке.", + "ofUnlimited": "из неограниченного", + "ofLimit": "из {{limit}}", + "overLimit": "Превышен лицензионный лимит — данные сверх лимита под угрозой.", + "configured": "настроено" + }, + "support": { + "title": "Поддержка", + "docs": "Документация", + "repo": "Репозиторий GitHub", + "issues": "Сообщить о проблеме", + "website": "utmstack.com" + }, + "legal": { + "title": "Юридическая информация", + "license": "Лицензия", + "security": "Сообщение об уязвимости", + "copyright": "© {{year}} UTMStack. Все права защищены." + } }, - "health": { - "title": "Состояние системы", - "details": "Подробности", - "services": { - "backend": "Backend API", - "opensearch": "Кластер OpenSearch", - "socai": "Движок SOC-AI" - }, - "detail": { - "noClusterInfo": "нет данных о кластере", - "disabled": "отключено", - "tools": "инструментов: {{n}}", - "unreachable": "недоступен", - "pending": "…" - } - } - }, - "nav": { - "home": "Главная", - "dashboards": "Панели", - "dashboardList": "Список панелей", - "visualizationList": "Список виджетов", - "newDashboard": "Новая панель", - "newVisualization": "Новый виджет", - "threatManagement": "Управление угрозами", - "alerts": "Оповещения", - "incidents": "Инциденты", - "adversaryView": "Обзор противников", - "soar": "SOAR", - "flows": "Потоки", - "executionHistory": "История выполнений", - "interactiveConsole": "Интерактивная консоль", - "logExplorer": "Обозреватель логов", - "userAuditor": "Аудит пользователей", - "threatIntelligence": "Аналитика угроз", - "threat-intel": { - "indicators": "Индикаторы", - "analyzt": "ИИ-аналитик", - "triage": "Триаж", - "report": "Отчёт" + "logExplorer": { + "title": "Просмотр логов", + "eventsIn": "событий в", + "searching": "Поиск…", + "query": { + "allDataTypes": "Все типы данных", + "dataTypes": "Типы данных", + "exportCsv": "Экспорт CSV", + "filterDataTypes": "Фильтр типов данных…", + "noDataTypes": "Нет типов данных", + "noDataTypesMatch": "Нет подходящих типов данных", + "noTextSearch": "У этого источника нет полнотекстового поля — фильтруйте по полю", + "refresh": "Обновить", + "run": "Выполнить", + "search": "Искать", + "searchPlaceholder": "Поиск по всем полям…" + }, + "time": { + "15m": "Последние 15 минут", + "1h": "Последний час", + "6h": "Последние 6 часов", + "24h": "Последние 24 часа", + "7d": "Последние 7 дней", + "30d": "Последние 30 дней" + }, + "ops": { + "is": "равно", + "isNot": "не равно", + "contains": "содержит", + "exists": "существует", + "between": "между", + "search": "поиск", + "isOneOf": "один из", + "isNotOneOf": "no es ninguno de", + "doesNotContain": "no contiene", + "startsWith": "empieza con", + "doesNotStartWith": "no empieza con", + "endsWith": "termina con", + "doesNotEndWith": "no termina con", + "doesNotExist": "no existe", + "notBetween": "no está entre", + "greaterThan": "es mayor que", + "greaterThanOrEquals": "es mayor o igual que", + "lessThan": "es menor que", + "lessThanOrEquals": "es menor o igual que" + }, + "filters": { + "label": "Фильтры", + "clearAll": "Очистить всё" + }, + "fields": { + "title": "Поля", + "filterPlaceholder": "Фильтр полей…", + "none": "Нет полей", + "selected": "Выбранные поля", + "available": "Доступные поля", + "topValues_one": "Топ {{count}} значение", + "topValues_few": "Топ {{count}} значения", + "topValues_many": "Топ {{count}} значений", + "topValues_other": "Топ {{count}} значений", + "loading": "Загрузка…", + "noValues": "Нет значений", + "addColumn": "Добавить как столбец", + "removeColumn": "Убрать столбец из таблицы", + "filterFor": "Фильтровать по значению", + "filterOut": "Исключить значение", + "empty": "(пусто)" + }, + "results": { + "dataTypesFailed": "Не удалось загрузить типы данных.", + "endOfResults": "Загружено событий: {{count}}", + "loadingMore": "Загрузка ещё…", + "message": "Сообщение", + "none": "Нет логов по этому запросу.", + "removeColumn": "Убрать {{field}}", + "retry": "Повторить", + "searchFailed": "Поиск не удался.", + "searching": "Поиск…", + "source": "Источник", + "time": "Время", + "scope": "Поиск выполнен в {{dataset}} · {{dataType}}.", + "searchAllDataTypes": "Искать по всем типам" + }, + "detail": { + "fieldsCount_one": "{{count}} поле", + "fieldsCount_few": "{{count}} поля", + "fieldsCount_many": "{{count}} полей", + "fieldsCount_other": "{{count}} полей", + "copyJson": "Копировать JSON", + "copied": "Документ скопирован", + "parsedFields": "Разобранные поля", + "json": "JSON", + "filterFor": "Фильтровать по", + "filterOut": "Исключить", + "surrounding": "Окружающие события", + "surroundingHint": "Показать события ±15 мин вокруг этого, из того же источника" + }, + "view": { + "table": "Таблица", + "chart": "График" + }, + "chart": { + "aggregateOn": "Агрегировать по", + "per": "по", + "topValues": "— топ 20 значений", + "building": "Построение графика…", + "failed": "Не удалось построить график для этого поля.", + "noData": "Нет данных для графика." + }, + "intervals": { + "minute": "Минута", + "hour": "Час", + "day": "День", + "week": "Неделя", + "month": "Месяц", + "quarter": "Квартал", + "year": "Год" + }, + "toast": { + "exportFailed": "Экспорт не удался" + }, + "builder": { + "add": "Добавить фильтр", + "filterValues": "Фильтр значений…", + "loadingValues": "Загрузка значений…", + "noValues": "Значения не найдены.", + "cancel": "Отмена", + "confirm": "Добавить", + "pickValue": "Pick a value to add the filter." + }, + "related": { + "nLogs_one": "{{count}} лог", + "nLogs_other": "{{count}} логов", + "truncated": "Показаны первые {{count}} связанных логов (полный набор больше)." + }, + "saved": { + "title": "Сохранённые", + "empty": "Сохранённых запросов пока нет", + "saveCurrent": "Сохранить текущий запрос", + "save": "Сохранить", + "namePlaceholder": "Название запроса", + "delete": "Удалить", + "saved": "Сохранено «{{name}}»", + "loading": "Загрузка…", + "loadFailed": "Не удалось загрузить сохранённые запросы", + "saveFailed": "Не удалось сохранить запрос", + "deleteFailed": "Не удалось удалить запрос", + "unreadable": "Не удалось прочитать этот сохранённый запрос" + } }, - "compliance": "Соответствие", - "configure": "Настройка", - "dataSources": "Источники данных", - "integrations": "Интеграции", - "alertingRules": "Правила оповещений", - "dataProcessing": "Обработка данных", - "team": "Команда", - "settings": "Настройки", - "back": "Назад", - "regexPatterns": "Регулярные выражения", - "taggingRules": "Правила тегирования", - "parsingFilters": "Пайплайны", - "overview": "Обзор", - "tenants": "Арендаторы", - "openMenu": "Открыть меню", - "closeMenu": "Закрыть меню", - "liveOps": "Мониторинг онлайн" - }, - "dashboards": { - "title": "Панели", - "subtitle": "Просмотр и редактирование интерактивных панелей.", - "list": { - "title": "Панели", - "create": "Создать", - "searchPlaceholder": "Поиск панелей…", - "loading": "Загрузка панелей…", - "empty": "Панелей пока нет.", - "rename": "Переименовать", - "delete": "Удалить" + "integrations": { + "title": "Интеграции", + "searchPlaceholder": "Поиск интеграций…", + "noMatch": "Нет совпадающих интеграций.", + "browseMarketplace": "Обзор marketplace", + "loading": "Загрузка интеграций…", + "addCustom": { + "title": "Добавить пользовательскую интеграцию", + "description": "Создать новый пользовательский источник", + "cta": "Создать" + }, + "tabs": { + "all": "Все", + "agents": "Агенты", + "collectors": "Коллекторы", + "cloud": "Cloud", + "custom": "Пользовательская" + }, + "kind": { + "agents & syslog": "Агент", + "device": "Коллектор", + "antivirus": "Коллектор", + "other": "Коллектор", + "custom": "Пользовательская", + "cloud": "Cloud", + "utmstack modules": "Коллектор" + }, + "status": { + "configured": "Настроена", + "available": "Доступна" + }, + "card": { + "manage": "Управлять →", + "setup": "Настроить →", + "eventsPerSec": "{{rate}} с/с", + "enabled": "Включено", + "setupShort": "Настроить" + }, + "drawer": { + "manage": "Управлять", + "viewEvents": "Просмотр событий", + "documentation": "Документация", + "getInstallCmd": "Получить команду установки", + "setupCollector": "Настроить коллектор", + "connect": "Подключить", + "configureCustom": "Настроить пользовательский источник", + "eventsRate": "{{rate}} событий/с · {{count}} за 24ч", + "manageRules": "Правила", + "manageFilters": "Фильтры", + "openDashboard": "Abrir panel" + }, + "setup": { + "agent": { + "howItWorksTitle": "Как это работает", + "howItWorksBody": "Агент {{name}} — это небольшой демон, работающий на хосте и пересылающий локальные события в UTMStack по аутентифицированному TLS-соединению. Он обновляется автоматически и сообщает о своем состоянии здоровья.", + "installTitle": "Установить на {{name}}", + "installHint": "Выполните эту команду на каждом хосте {{name}}, который вы хотите отслеживать. Токен уже кодирует ваше текущее рабочее пространство.", + "afterTitle": "Что вы увидите после установки", + "after1": "Хост появляется в разделе Источники данных примерно через 60 секунд после запуска агента.", + "after2": "Телеметрия начинает поступать в Log Explorer, ограничиваясь вашим рабочим пространством.", + "after3": "Агент автоматически сообщает состояние CPU/памяти/диска обратно в UTMStack.", + "actionLabel": "Действие", + "platformLabel": "Платформа", + "optionsLabel": "Опции", + "skipCertValidation": "Не проверять TLS-сертификат (самоподписанный сервер)", + "noRemoteControl": "Отключить удалённое выполнение команд на этом хосте", + "loadingToken": "Загрузка токена…", + "actions": { + "install": "Установить", + "uninstall": "Удалить" + }, + "prereqTitle": "Требования перед установкой", + "prereqBody": "Агент UTMStack взаимодействует с сервером через следующие порты. Убедитесь, что они открыты между хостом и UTMStack перед установкой:", + "sensitiveWarning": "Команда ниже содержит конфиденциальный токен регистрации — не передавайте его третьим лицам.", + "uninstall": { + "title": "Удалить агент", + "body": "Выполните это на хосте, чтобы остановить и удалить агент UTMStack и его службы. Используется платформа, выбранная выше." + }, + "macCompat": "Требуется macOS 11 (Big Sur) или новее на Apple Silicon (M1/M2/M3 или новее). Mac на базе Intel не поддерживаются." + }, + "collector": { + "howItWorksTitle": "Как это работает", + "howItWorksBody": "{{name}} не запускает агент UTMStack. Вместо этого вы устанавливаете коллектор UTMStack где-нибудь в сети, которая доступна как вашему устройству {{name}}, так и UTMStack. {{name}} отправляет syslog на коллектор, коллектор анализирует, нормализует и пересылает события в UTMStack.", + "step1Title": "1 · Установить коллектор UTMStack", + "step1Hint": "Запустите на хосте Linux с сетевым доступом с устройства {{name}}.", + "step2Title": "2 · Настроить {{name}} для отправки syslog", + "step2Hint": "На устройстве {{name}} направьте пересылку syslog на адрес коллектора на {{port}}.", + "vendorDocs": "Смотрите инструкции для конкретного поставщика", + "step3Title": "3 · Проверка", + "step3Body": "Через несколько минут вы должны увидеть события {{name}} в source: {{source}} в Log Explorer и новую запись в Источниках данных.", + "endpoint": { + "title": "Параметры подключения", + "hint": "Настройте {{name}} для пересылки журналов на Collector, используя хост и порт ниже." + }, + "syslog": { + "sections": { + "sendLogs": { + "title": "1 · Отправка журналов в UTMStack", + "body": "Настройте устройство для отправки syslog-сообщений по UDP (514) или TCP (514) на агент UTMStack." + }, + "enableCollector": { + "title": "2 · Включение syslog-коллектора", + "body": "Включите коллектор журналов и syslog-интеграцию в файле конфигурации там, где установлен агент UTMStack." + }, + "activate": { + "title": "3 · Активация", + "body": "Активируйте модуль UTMStack, чтобы события начали поступать в Log Explorer." + } + } + }, + "netflow": { + "source": "Сетевое устройство", + "step1": { + "title": "Включить слушатель NetFlow на Collector", + "body": "На хосте, где установлен Collector, выполните эту команду, чтобы открыть коллектор NetFlow на порту 2055:", + "note": "NetFlow использует только UDP — TCP и TLS не поддерживаются для этого протокола." + }, + "step2": { + "title": "Настройте устройство для экспорта NetFlow", + "body": "Направьте экспорт NetFlow с вашего маршрутизатора или межсетевого экрана на Collector-хост, порт {{port}} UDP. Пример ниже предназначен для Cisco IOS — для других платформ обратитесь к документации производителя:", + "note": "Замените на имя интерфейса, на котором должен отслеживаться трафик (например, GigabitEthernet0/0). Примените ingress/egress для каждого нужного интерфейса." + } + }, + "cisco": { + "source": "Cisco ASA", + "step1": { + "title": "Включить слушатель Cisco ASA на Collector", + "body": "На хосте, где установлен Collector, выполните эту команду, чтобы открыть слушатель журналов Cisco ASA:", + "note": "Чтобы использовать TCP вместо UDP, замените udp на tcp в приведённой выше команде." + }, + "step2": { + "title": "Настроить Cisco ASA для пересылки журналов", + "body": "На вашем Cisco ASA включите syslog и направьте его на Collector-хост, порт {{port}}. Выполните эти команды в привилегированном режиме EXEC (замените на имя внутреннего или управляющего интерфейса):" + } + }, + "ciscoSwitch": { + "source": "Cisco Switch", + "step1": { + "title": "Включить слушатель Cisco Switch на Collector", + "body": "На хосте, где установлен Collector, выполните эту команду, чтобы открыть слушатель журналов Cisco Switch:", + "note": "Чтобы использовать TCP вместо UDP, замените udp на tcp в приведённой выше команде." + }, + "step2": { + "title": "Настроить коммутатор для пересылки журналов", + "body": "В привилегированном режиме EXEC на вашем коммутаторе Cisco включите syslog и направьте его на Collector-хост, порт {{port}}:" + } + }, + "ciscoMeraki": { + "source": "Cisco Meraki", + "step1": { + "title": "Включить слушатель Cisco Meraki на Collector", + "body": "На хосте, где установлен Collector, выполните эту команду, чтобы открыть слушатель журналов Cisco Meraki:", + "note": "Чтобы использовать TCP вместо UDP, замените udp на tcp в приведённой выше команде." + }, + "step2": { + "title": "Настроить Meraki для пересылки журналов", + "body": "В Meraki Dashboard перейдите в Network-wide → Configure → General, прокрутите до раздела Reporting и добавьте syslog-сервер с IP Collector и портом {{port}}. Выберите все роли, которые нужно пересылать." + } + }, + "ciscoFirepower": { + "source": "Cisco Firepower", + "step1": { + "title": "Включить слушатель Cisco Firepower на Collector", + "body": "На хосте, где установлен Collector, выполните эту команду, чтобы открыть слушатель журналов Cisco Firepower:", + "note": "Чтобы использовать TCP вместо UDP, замените udp на tcp в приведённой выше команде." + }, + "step2": { + "title": "Настроить Firepower для пересылки журналов", + "body": "В Firepower Management Center (FMC) перейдите в Devices → Platform Settings, отредактируйте или создайте политику и перейдите в Syslog → Syslog Servers. Добавьте IP Collector с портом {{port}} (UDP), затем назначьте политику вашим устройствам и выполните развёртывание." + } + }, + "vmware": { + "source": "VMware ESXi", + "step1": { + "title": "Включить слушатель VMware на Collector", + "body": "На хосте, где установлен Collector, выполните эту команду, чтобы открыть syslog-слушатель VMware ESXi. ESXi передаёт данные по TCP:", + "note": "Для зашифрованного канала используйте tls вместо tcp (предварительно загрузите сертификаты на Collector)." + }, + "step2": { + "title": "Направить syslog ESXi на Collector", + "body": "Откройте сессию SSH/ESXi Shell на хосте (или используйте vSphere Client: Host → Configure → Advanced System Settings → Syslog.global.logHost). Задайте удалённый loghost как {{host}}:{{port}} и перезагрузите конфигурацию:", + "note": "В vSphere можно вместо этого задать Syslog.global.logHost с тем же значением tcp://host:port, не выполняя esxcli." + }, + "step3": { + "title": "Открыть порт syslog в брандмауэре ESXi", + "body": "Разрешите исходящий syslog через брандмауэр ESXi, чтобы хост мог достичь Collector:" + } + }, + "as400": { + "intro": { + "title": "Принцип работы", + "body": "Коллектор AS/400 — это Linux-служба, которая напрямую подключается к вашим системам AS/400 (IBM i), извлекает записи журнала безопасности и безопасно передаёт их в UTMStack для корреляции и оповещения.", + "note": "На самом AS/400 ничего не устанавливается — Коллектор работает на Linux-хосте, имеющем сетевой доступ к вашим системам AS/400.", + "diagram": { + "source": "ваши журналы", + "edge1": "журналы", + "collector": "AS/400 Collector", + "collectorSub": "извлекает из AS/400", + "edge2": "защищённый канал", + "utmstackSub": "оповещения и корреляция" + } + }, + "install": { + "title": "Установить AS/400 Collector", + "body": "Выполните эту команду на Linux-хосте, который имеет сетевой доступ к UTMStack и вашим системам AS/400.", + "reuse": "AS/400 Collector уже установлен? Пропустите этот шаг — просто добавьте серверы в файл конфигурации на следующем шаге." + }, + "configure": { + "title": "Добавить серверы AS/400", + "body": "Отредактируйте as400-config.yaml в каталоге установки коллектора и добавьте каждую систему AS/400, которую хотите отслеживать:", + "note": "Вы можете указать несколько серверов. Коллектор отслеживает этот файл и автоматически перезагружается при сохранении — перезапуск не требуется." + }, + "journal": { + "title": "Включить аудит журналирования на AS/400", + "body": "На каждой системе AS/400 убедитесь, что журнал аудита безопасности QAUDJRN активен. Обратитесь к документации IBM за точными шагами — процедура различается в зависимости от версии IBM i." + }, + "uninstall": { + "title": "Необязательно — удалить Collector", + "body": "Выполните эту команду на хосте, где установлен AS/400 Collector, чтобы остановить службу и удалить все файлы." + } + }, + "bitdefender": { + "intro": { + "title": "Принцип работы", + "body": "UTMStack подключается к Bitdefender GravityZone с использованием вашего API-ключа для настройки Event Push Service. Затем GravityZone отправляет события безопасности непосредственно в UTMStack для корреляции и оповещения.", + "diagram": { + "source": "события конечных точек", + "edge": "Event Push Service", + "utmstackSub": "оповещения и корреляция" + }, + "note": "На GravityZone ничего не устанавливается — UTMStack регистрирует себя в качестве адресата push-уведомлений с использованием API-учётных данных только для чтения." + }, + "whitelist": { + "title": "Добавить IP-адреса Bitdefender в белый список", + "body": "Следующие IP-адреса Bitdefender GravityZone должны быть разрешены в вашем брандмауэре на порту 8000, чтобы Event Push Service мог достичь UTMStack:", + "note": "Добавьте эти IP-адреса в ваш брандмауэр или группу безопасности перед завершением настройки." + }, + "apiSection": "Получить учётные данные API", + "api": { + "myAccount": { + "title": "Открыть «Мой аккаунт»", + "body": "В консоли Bitdefender GravityZone нажмите My Account." + }, + "accessUrl": { + "title": "Записать Access URL", + "body": "Прокрутите вниз до раздела Control Center API и сохраните Access URL — он понадобится при заполнении формы учётных данных ниже. Затем откройте раздел API-ключей и нажмите Add в верхней части таблицы." + }, + "createKey": { + "title": "Создать API-ключ", + "body": "Введите описание для API-ключа, выберите параметр Event Push Service API и нажмите Save. Скопируйте сгенерированный ключ." + } + }, + "companySection": "Получить идентификаторы компаний", + "company": { + "myCompany": { + "title": "Открыть «Моя компания»", + "body": "В консоли GravityZone нажмите My Company." + }, + "licensing": { + "title": "Записать идентификаторы компаний", + "body": "Откройте раздел Licensing и сохраните идентификаторы компаний, которые хотите отслеживать — введите их через запятую в форме учётных данных ниже." + } + }, + "credentials": { + "title": "Ввести учётные данные", + "body": "Введите URL доступа, API-ключ, публичный IP-адрес UTMStack (на который GravityZone будет отправлять события) и идентификаторы компаний для мониторинга. UTMStack проверяет учётные данные перед сохранением." + }, + "fields": { + "accessUrl": { + "label": "URL доступа GravityZone" + }, + "connectionKey": { + "label": "API-ключ" + }, + "utmPublicIP": { + "label": "Публичный IP-адрес UTMStack" + }, + "companyIds": { + "label": "Идентификаторы компаний (через запятую)" + } + } + }, + "eset": { + "source": "ESET Protect", + "step1": { + "title": "Включите обработчик ESET на Collector", + "body": "На хосте, где установлен Collector, выполните следующую команду для запуска syslog-обработчика ESET:", + "note": "Чтобы использовать TCP вместо UDP, замените udp на tcp в приведённой выше команде." + }, + "console": { + "moreMenu": { + "title": "Откройте меню «Дополнительно»", + "body": "На боковой панели консоли ESET Protect нажмите меню Дополнительно." + }, + "serverConfig": { + "title": "Откройте настройки сервера", + "body": "В разделе «Дополнительно» откройте раздел Настройки сервера (конфигурация сервера)." + }, + "advanced": { + "title": "Разверните расширенные настройки", + "body": "Нажмите Расширенные настройки, чтобы открыть полный список параметров конфигурации." + }, + "syslog": { + "title": "Настройте Syslog-сервер", + "body": "Прокрутите до Syslog server, включите Export logs to Syslog и укажите в качестве назначения хост Collector на порту {{port}} (UDP). ESET отправляет LEEF/syslog, который Collector принимает как тип данных antivirus-esmc-eset." + } + } + }, + "kaspersky": { + "source": "Kaspersky Security", + "step1": { + "title": "Включите обработчик Kaspersky на Collector", + "body": "На хосте, где установлен Collector, выполните следующую команду для запуска syslog-обработчика Kaspersky:", + "note": "Чтобы использовать TCP вместо UDP, замените udp на tcp в приведённой выше команде." + }, + "console": { + "consoleSettings": { + "title": "Откройте «Настройки консоли» → «Интеграция»", + "body": "На боковой панели Kaspersky Security Center откройте Настройки консоли и нажмите подменю Интеграция." + }, + "siem": { + "title": "Откройте настройки интеграции SIEM", + "body": "В разделе «Интеграция» выберите SIEM и нажмите ссылку Настройки, чтобы открыть конфигурацию экспорта." + }, + "configure": { + "title": "Настройте экспорт SIEM", + "body": "Включите экспорт и настройте Kaspersky для отправки событий в формате Splunk (CEF) на хост Collector через порт {{port}} (UDP). Collector принимает их как тип данных antivirus-kaspersky." + } + } + }, + "sophos": { + "intro": { + "title": "Sophos Central — API Plugin", + "body": "Sophos Central предоставляет защищённые API для получения данных о событиях и предупреждениях. UTMStack подключается к этим API для централизованного мониторинга и повышения видимости безопасности — агент или Collector не требуется.", + "diagram": { + "source": "Sophos Central API", + "edge": "HTTPS API", + "utmstackSub": "Приём и корреляция" + }, + "note": "UTMStack опрашивает Sophos Central API по расписанию. Убедитесь, что создаваемые ниже учётные данные API имеют доступ на чтение событий и предупреждений." + }, + "apiSection": "Создание учётных данных API в Sophos Central", + "steps": { + "apiCredentials": { + "title": "Откройте управление учётными данными API", + "body": "В Sophos Central Admin перейдите в Global Settings → API Credentials Management." + }, + "addCredential": { + "title": "Создайте новые учётные данные", + "body": "Нажмите Add Credential. Укажите Name и Description, выберите подходящую Role, затем нажмите Add." + }, + "copyIds": { + "title": "Скопируйте Client ID и Client Secret", + "body": "Скопируйте Client ID и Client Secret и сохраните в надёжном месте.", + "secretNote": "Client Secret отображается только один раз. Сохраните его в надёжном месте, не закрывая это диалоговое окно." + } + }, + "credentialsSection": "Подключение к UTMStack", + "credentials": { + "title": "Добавьте учётные данные Sophos Central", + "body": "Введите только что созданные учётные данные. Вы можете добавить несколько учётных записей Sophos, нажав «Добавить группу конфигурации»." + }, + "fields": { + "clientId": { + "label": "Client ID" + }, + "apiKey": { + "label": "Client Secret / API-ключ" + } + } + }, + "webroot": { + "sections": { + "login": { + "title": "1 · Войдите в консоль управления", + "body": "Войдите в консоль управления Webroot. Она открывается на вкладке Sites." + }, + "openSettings": { + "title": "2 · Откройте «Настройки»", + "body": "Перейдите на вкладку Settings." + }, + "apiAccess": { + "title": "3 · Откройте доступ к API", + "body": "На вкладке Subscriptions нажмите вкладку API Access." + }, + "createCredential": { + "title": "4 · Создайте клиентские учётные данные", + "body": "Нажмите New и заполните поля Name и Description. Ознакомьтесь с соглашением SecureAnywhere Business Solution и Unity API, затем нажмите Create." + }, + "noteClientSecret": { + "title": "5 · Скопируйте Client ID и секрет клиента", + "body": "Сохраните Client ID из списка и Client Secret, который отображается только один раз. Нажмите «I have made note of the client secret» для подтверждения." + }, + "fillForm": { + "title": "6 · Заполните форму", + "body": "Укажите Client ID и Client Secret в UTMStack. При необходимости вы можете добавить несколько групп конфигурации Webroot." + }, + "activate": { + "title": "7 · Активация", + "body": "Активируйте модуль UTMStack, чтобы начать получать события Webroot." + } + } + }, + "sentinelOne": { + "source": "SentinelOne", + "step1": { + "title": "Включите обработчик SentinelOne на Collector", + "body": "На хосте, где установлен Collector, выполните следующую команду для запуска syslog-обработчика SentinelOne. SentinelOne передаёт CEF по TCP:", + "note": "Для зашифрованного канала используйте tls вместо tcp (предварительно загрузите сертификаты на Collector)." + }, + "console": { + "settings": { + "title": "Откройте настройки SentinelOne", + "body": "На боковой панели консоли управления SentinelOne нажмите меню Настройки." + }, + "syslog": { + "title": "Настройте интеграцию Syslog", + "body": "Перейдите в Integrations → Syslog и включите. Укажите хост {{host}} и порт {{port}}, оставьте формат CEF, нажмите Test для проверки соединения, затем Save." + } + } + }, + "office365": { + "intro": { + "title": "Как это работает", + "body": "UTMStack подключается к Microsoft 365 с помощью зарегистрированного приложения Azure AD и опрашивает Office 365 Management Activity API для получения событий аудита и безопасности. Агент в вашем тенанте не устанавливается.", + "diagram": { + "source": "события аудита и безопасности", + "edge": "Management API", + "utmstackSub": "корреляция и оповещения" + }, + "note": "UTMStack требует доступа к API только для чтения — разрешения на запись не запрашиваются." + }, + "appSection": "Регистрация приложения Azure", + "steps": { + "azurePortal": { + "title": "Откройте Microsoft Entra ID", + "body": "Откройте Azure Portal (portal.azure.com) и нажмите Microsoft Entra ID." + }, + "appRegistrations": { + "title": "Перейдите в «Регистрации приложений»", + "body": "В левом меню нажмите Регистрации приложений." + }, + "registerApp": { + "title": "Зарегистрируйте новое приложение", + "body": "Нажмите Новая регистрация. Введите имя UTMStack O365 Agent, выберите Учётные записи только в этом каталоге организации (один клиент) и нажмите Зарегистрировать." + }, + "clientSecret": { + "title": "Создайте секрет клиента", + "body": "Перейдите в Сертификаты и секреты → Новый секрет клиента. Добавьте описание, установите срок действия 730 дней (24 месяца) и нажмите Добавить.", + "copyNote": "Немедленно скопируйте значение секрета — оно отображается только один раз и впоследствии недоступно." + }, + "apiPermissions": { + "title": "Добавьте разрешения Office 365 Management API", + "body": "Перейдите в Разрешения API → Добавить разрешение и найдите Office 365 Management APIs." + }, + "activityFeed": { + "title": "Предоставьте разрешения ActivityFeed", + "body": "Выберите Разрешения приложения и добавьте ActivityFeed.Read и ActivityFeed.ReadDlp. Нажмите Предоставить согласие администратора и подтвердите." + }, + "graphPermissions": { + "title": "Добавьте разрешения Microsoft Graph", + "body": "Вернитесь в Добавить разрешение и нажмите Microsoft Graph." + }, + "delegatedPermissions": { + "title": "Добавьте делегированные разрешения SecurityAlert", + "body": "Выберите Делегированные разрешения и добавьте SecurityAlert.Read.All и SecurityAlert.ReadWrite.All. Нажмите Предоставить согласие администратора и подтвердите." + }, + "appPermissions": { + "title": "Добавьте разрешения приложения SecurityAlert", + "body": "Выберите Разрешения приложения и добавьте SecurityAlert.Read.All и SecurityAlert.ReadWrite.All. Нажмите Предоставить согласие администратора и подтвердите." + }, + "noteIds": { + "title": "Скопируйте идентификаторы приложения", + "body": "Перейдите в раздел Обзор приложения и скопируйте Идентификатор приложения (клиента) и Идентификатор каталога (тенанта). Также потребуется значение секрета, скопированное на шаге 4." + } + }, + "credentialsSection": "Учётные данные", + "credentials": { + "title": "Подключите тенант Microsoft 365", + "body": "Введите данные из шагов выше. UTMStack проверяет учётные данные перед сохранением. Вы можете добавить несколько групп конфигурации." + }, + "fields": { + "tenantId": { + "label": "Идентификатор тенанта (Directory ID)" + }, + "clientId": { + "label": "Client ID (Application ID)" + }, + "clientSecret": { + "label": "Client Secret" + }, + "cloudEnv": { + "label": "Облачная среда (необязательно)", + "hint": "Commercial (по умолчанию), GCC, GCCHigh или DoD" + } + } + }, + "github": { + "source": "GitHub", + "step1": { + "title": "Включить прослушиватель webhook GitHub на Collector", + "body": "На хосте, где установлен Collector, выполните эту команду, чтобы открыть прослушиватель webhook HTTPS для GitHub:", + "tokenNote": "Терминал выведет секретный токен — скопируйте его немедленно. Он больше не будет показан." + }, + "certWarning": { + "title": "GitHub требует TLS-сертификат, подписанный центром сертификации", + "body": "GitHub доставляет вебхуки только на конечные точки HTTPS с сертификатом, выданным публичным центром сертификации (самоподписанные сертификаты отклоняются). Убедитесь, что хост Collector имеет действующий доменный сертификат до регистрации вебхука." + }, + "step2": { + "title": "Зарегистрировать вебхук в GitHub", + "body": "В вашем репозитории или организации перейдите в Settings → Webhooks → Add webhook и заполните форму:", + "payloadUrl": "URL полезной нагрузки", + "contentType": "Тип содержимого", + "secret": "Секрет", + "secretHint": "Вставьте токен, выведенный Collector на предыдущем шаге.", + "events": "Какие события", + "eventsHint": "Отправлять всё — или выбрать определённые типы событий." + } + }, + "salesforce": { + "sections": { + "openSetup": { + "title": "1 · Открыть Setup", + "body": "Перейдите в Setup и выберите «Setup for the current app» в правом верхнем углу экрана." + }, + "appManager": { + "title": "2 · Открыть App Manager", + "body": "Введите «App Manager» в строке быстрого поиска и выберите App Manager." + }, + "newConnectedApp": { + "title": "3 · Создать новое Connected App", + "body": "На экране Lightning Experience App Manager нажмите «New Connected App» и заполните поля." + }, + "oauthSettings": { + "title": "4 · Включить OAuth Settings", + "body": "В разделе «API (Enable OAuth Settings)» установите флажок «Enable OAuth Settings» и укажите https://login.salesforce.com/services/oauth2/success в качестве Callback URL." + }, + "oauthScopes": { + "title": "5 · Добавить OAuth scopes", + "body": "Выберите «Access Connect REST API resources (chatter_api)» в разделе Selected OAuth Scopes." + }, + "save": { + "title": "6 · Сохранить", + "body": "Сохраните изменения и нажмите Continue на следующем экране." + }, + "manageConsumer": { + "title": "7 · Открыть Manage Consumer Details", + "body": "Внутри Connected App перейдите в «API (Enable OAuth Settings)» и нажмите «Manage Consumer Details» рядом с Consumer Key и Secret." + }, + "copyCredentials": { + "title": "8 · Скопировать Consumer Key и Secret", + "body": "Подтвердите личность. Consumer Key и Consumer Secret отображаются в разделе «Consumer Details». Скопируйте оба с помощью кнопки Copy." + }, + "fillForm": { + "title": "9 · Заполнить форму", + "body": "Укажите Consumer Key, Consumer Secret, имя пользователя и пароль Salesforce в UTMStack." + }, + "activate": { + "title": "10 · Активировать", + "body": "Активируйте модуль UTMStack, чтобы события Salesforce начали поступать." + } + } + }, + "iis": { + "sections": { + "enableModule": { + "title": "1 · Включить модуль IIS Filebeat", + "body": "На хосте агента UTMStack выполните:\ncd \"C:\\Program Files\\UTMStack\\UTMStack Agent\\beats\\filebeat\\\" && filebeat modules enable iis" + }, + "configureModule": { + "title": "2 · Настроить модуль IIS", + "body": "Отредактируйте C:\\Program Files\\UTMStack\\UTMStack Agent\\beats\\filebeat\\modules.d\\iis.yml, как показано ниже, чтобы указать каталоги журналов IIS для отправки." + }, + "activate": { + "title": "3 · Активировать", + "body": "Активируйте модуль UTMStack, чтобы события IIS начали поступать." + } + } + }, + "filebeat": { + "sections": { + "installRsyslog": { + "title": "1 · Установить rsyslog", + "body": "Убедитесь, что rsyslog установлен на хосте. Используйте менеджер пакетов вашего дистрибутива (apt, dnf, yum)." + }, + "configureRsyslog": { + "title": "2 · Настроить rsyslog для пересылки в UTMStack", + "body": "Отредактируйте /etc/rsyslog.conf (или файл в /etc/rsyslog.d/) и добавьте правило пересылки, направляющее трафик на агент UTMStack по UDP или TCP на порту 514." + }, + "restartRsyslog": { + "title": "3 · Перезапустить rsyslog", + "body": "Перезапустите службу rsyslog: sudo systemctl restart rsyslog" + }, + "enableCollector": { + "title": "4 · Включить сборщик журналов Linux", + "body": "Включите сборщик журналов и интеграцию Linux Logs в конфигурационном файле там, где установлен агент UTMStack." + } + } + }, + "json": { + "sections": { + "overview": { + "title": "1 · Использовать конечную точку приёма HTTP/JSON", + "body": "UTMStack принимает произвольные JSON-события по HTTPS. Отправьте POST-запрос со списком событий; UTMStack разберёт их и направит через настроенный парсер." + }, + "auth": { + "title": "2 · Аутентификация с помощью токена федерации", + "body": "Получите токен федерации в Settings → Connection Key и передайте его как Bearer-токен в заголовке Authorization." + } + }, + "endpoint": { + "title": "Конечная точка приёма JSON", + "hint": "Используйте этот формат запроса из вашего приложения или задания cron. Токен — это ключ федерации из Settings → Connection Key." + } + }, + "ldap": { + "sections": { + "openServerManager": { + "title": "1 · Открыть Server Manager", + "body": "На контроллере домена AD откройте Server Manager." + }, + "addRoles": { + "title": "2 · Добавить роли и компоненты", + "body": "Выберите «Add roles and features» в меню Manage." + }, + "selectCertServices": { + "title": "3 · Выбрать Active Directory Certificate Services", + "body": "На шаге Server Roles выберите Active Directory Certificate Services." + }, + "installServices": { + "title": "4 · Установить службу роли Центра сертификации", + "body": "На шаге Role Services выберите Certificate Authority и завершите работу мастера." + }, + "configureAdCs": { + "title": "5 · Настроить AD CS", + "body": "После установки нажмите на уведомление для настройки AD CS и выберите Certificate Authority в качестве службы роли для настройки." + }, + "pickCaType": { + "title": "6 · Выбрать тип ЦС", + "body": "Выберите Enterprise CA → Root CA → Create a new private key." + }, + "setValidity": { + "title": "7 · Установить срок действия сертификата", + "body": "Установите срок действия, соответствующий требованиям вашей организации (обычно 5 лет)." + }, + "confirm": { + "title": "8 · Подтвердить и установить", + "body": "Проверьте настройки и нажмите Configure для завершения." + }, + "restart": { + "title": "9 · Перезапустить контроллер домена", + "body": "Перезапустите контроллер домена, чтобы LDAPS стал доступен на TCP 636." + }, + "activate": { + "title": "10 · Активировать", + "body": "Активируйте модуль UTMStack, чтобы события аудита AD начали поступать." + } + } + }, + "oracle": { + "source": "Сервер Oracle DB", + "step1": { + "title": "Включить интеграцию Oracle на Collector", + "body": "На сервере, где установлен Collector, выполните следующую команду, чтобы начать прослушивание журналов Oracle:", + "note": "Collector начнёт получать события syslog от Oracle на порту 7021." + }, + "step2": { + "title": "Настроить rsyslog на сервере Oracle", + "body": "Создайте файл конфигурации rsyslog:", + "editBody": "Откройте файл в предпочтительном редакторе и добавьте следующую конфигурацию. Замените BASEDIR путём установки Oracle (например, /u01/app/oracle), а — IP-адресом или именем хоста Collector:", + "note": "Используйте @@:7021 вместо @, если предпочитаете доставку по TCP." + }, + "step3": { + "title": "Перезапустить rsyslog", + "body": "Примените новую конфигурацию, перезапустив службу rsyslog:" + }, + "step4": { + "title": "Проверить конфигурацию", + "body": "Отправьте тестовые сообщения журнала, чтобы убедиться, что UTMStack получает события от всех трёх источников журналов Oracle:", + "note": "Откройте Log Explorer и найдите текст тестового сообщения выше, чтобы подтвердить его получение." + } + }, + "vulnerabilities": { + "sections": { + "overview": { + "title": "1 · О сканере уязвимостей", + "body": "Модуль уязвимостей UTMStack сканирует активы, обнаруженные через модуль Asset Management, и сопоставляет их отпечатки с базой данных CVE." + }, + "scope": { + "title": "2 · Определить область сканирования", + "body": "Используйте модуль Asset Management для регистрации хостов, которые необходимо сканировать. Сканер уязвимостей будет периодически проверять их." + }, + "activate": { + "title": "3 · Активировать", + "body": "Активируйте модуль UTMStack для запуска сканирования." + } + } + }, + "assetScanner": { + "sections": { + "overview": { + "title": "1 · Об управлении активами", + "body": "Модуль Asset Management обнаруживает и инвентаризирует хосты, программное обеспечение и сервисы в вашей сети." + }, + "agentRequirement": { + "title": "2 · Требования к агенту", + "body": "Обнаружение активов использует агенты UTMStack, работающие на хостах Linux, Windows или macOS. Установите агент на системы, которые необходимо инвентаризировать." + }, + "activate": { + "title": "3 · Активировать", + "body": "Активируйте модуль UTMStack, чтобы начать обнаружение активов." + } + } + }, + "fileIntegrity": { + "sections": { + "enableAuditPolicy": { + "title": "1 · Включить аудит доступа к объектам", + "body": "На хосте Windows откройте Group Policy → Computer Configuration → Windows Settings → Security Settings → Advanced Audit Policy Configuration → Object Access и включите \"Audit File System\"." + }, + "configureFolderAuditing": { + "title": "2 · Настроить аудит папок", + "body": "Для каждой папки, которую необходимо контролировать, откройте Properties → Security → Advanced → Auditing и добавьте запись аудита для нужных субъектов и типов доступа." + }, + "verifyEvents": { + "title": "3 · Проверить появление событий в журнале безопасности", + "body": "Откройте Event Viewer и убедитесь, что при обращении к аудируемым объектам генерируются события 4663/4670." + }, + "activate": { + "title": "4 · Активировать", + "body": "Активируйте модуль UTMStack, чтобы начали поступать события целостности файлов." + } + } + }, + "socAi": { + "sections": { + "overview": { + "title": "1 · О SOC AI", + "body": "SOC AI расширяет UTMStack аналитиком на основе LLM, который обобщает оповещения и предлагает дальнейшие шаги. Работает с выбранным вами провайдером." + }, + "chooseProvider": { + "title": "2 · Выбрать провайдера", + "body": "Выберите провайдера — OpenAI, Anthropic, Azure OpenAI, Google Gemini, Ollama, Mistral, DeepSeek, Groq или совместимый с OpenAI пользовательский endpoint." + }, + "configureCredentials": { + "title": "3 · Настроить учётные данные", + "body": "Укажите API-ключ, а также (при необходимости) название модели и URL endpoint." + }, + "activate": { + "title": "4 · Активировать", + "body": "Активируйте модуль UTMStack, чтобы SOC AI начал обрабатывать оповещения." + } + } + }, + "utmstack": { + "intro": { + "title": "Как это работает", + "body": "Эта интеграция обеспечивает самомониторинг вашего развёртывания UTMStack. Лёгкий коллектор, установленный на хосте UTMStack, отслеживает журналы контейнеров Docker самой платформы и передаёт их обратно в UTMStack для корреляции и создания оповещений.", + "diagram": { + "source": "Журналы Docker", + "sourceSub": "Контейнеры UTMStack", + "edge1": "отслеживание", + "collector": "Коллектор", + "collectorSub": "на хосте", + "edge2": "приём", + "utmstackSub": "Корреляция и оповещения" + } + }, + "requirements": { + "title": "Работает только на хосте UTMStack", + "body": "Эта интеграция может быть установлена только на экземпляр UTMStack под управлением Ubuntu или дистрибутива семейства Red Hat. Установите коллектор непосредственно на сервер UTMStack." + }, + "install": { + "title": "Установить коллектор", + "body": "На хосте UTMStack выберите операционную систему и выполните приведённую ниже команду для загрузки и установки коллектора самомониторинга:", + "sensitiveWarning": "Эта команда содержит конфиденциальный токен подключения. Обращайтесь с ним как с паролем и не передавайте его третьим лицам." + }, + "after": { + "title": "Что вы увидите после установки", + "item1": "Коллектор регистрируется и отображается в разделе Data sources.", + "item2": "Журналы контейнеров UTMStack начинают поступать в течение минуты.", + "item3": "События становятся доступны для поиска в Log Explorer в типе данных utmstack." + }, + "uninstall": { + "title": "Удалить коллектор", + "body": "Чтобы удалить коллектор самомониторинга с хоста UTMStack, выполните:" + } + }, + "windowsFaa": { + "sections": { + "enableAuditPolicy": { + "title": "1 · Включить аудит доступа к объектам", + "body": "На хосте Windows откройте Group Policy → Computer Configuration → Windows Settings → Security Settings → Advanced Audit Policy Configuration → Object Access и включите \"Audit File System\"." + }, + "configureFolderAuditing": { + "title": "2 · Настроить аудит папок", + "body": "Для каждой папки, которую необходимо контролировать, откройте Properties → Security → Advanced → Auditing и добавьте запись аудита для нужных субъектов и типов доступа." + }, + "activate": { + "title": "3 · Активировать", + "body": "Активируйте модуль UTMStack, чтобы начали поступать события файловой активности." + } + } + }, + "awsBeanstalk": { + "sections": { + "openConsole": { + "title": "1 · Открыть консоль Elastic Beanstalk", + "body": "В AWS Console откройте Elastic Beanstalk." + }, + "environment": { + "title": "2 · Открыть страницу управления окружением", + "body": "Перейдите на страницу управления окружением, которое необходимо отслеживать." + }, + "configuration": { + "title": "3 · Открыть раздел Configuration", + "body": "Выберите Configuration." + }, + "software": { + "title": "4 · Изменить конфигурацию Software", + "body": "В категории Software configuration выберите Modify." + }, + "s3LogStorage": { + "title": "5 · Включить хранение журналов в S3", + "body": "В разделе S3 log storage выберите Rotate logs для загрузки ротируемых журналов в Amazon S3." + }, + "cloudwatchStreaming": { + "title": "6 · Включить потоковую передачу CloudWatch Logs", + "body": "В разделе Instance log streaming to CloudWatch Logs включите потоковую передачу, задайте период хранения и выберите, загружать ли существующие журналы." + }, + "activate": { + "title": "7 · Активировать", + "body": "Активируйте модуль UTMStack, чтобы начали поступать события Beanstalk." + } + } + }, + "awsFargate": { + "sections": { + "taskDefinition": { + "title": "1 · Обновить определение задачи", + "body": "В определении задачи для Fargate задайте logDriver как \"awslogs\" и укажите имя группы журналов." + }, + "cloudwatchLogs": { + "title": "2 · Убедиться, что CloudWatch Logs получает журналы", + "body": "Откройте консоль CloudWatch Logs и убедитесь, что группа журналов заполняется при выполнении задач." + }, + "iamPrerequisite": { + "title": "3 · Предварительное условие: IAM-пользователь", + "body": "Эта интеграция использует общие учётные данные с модулем AWS IAM User — убедитесь, что он настроен с политикой CloudWatchLogsReadOnlyAccess." + }, + "activate": { + "title": "4 · Активировать", + "body": "Активируйте модуль UTMStack, чтобы начали поступать события Fargate." + } + } + }, + "awsIamUser": { + "sections": { + "iamConsole": { + "title": "1 · Открыть консоль IAM", + "body": "В консоли AWS перейдите в IAM → Users → Add users." + }, + "createUser": { + "title": "2 · Создать пользователя", + "body": "Введите имя пользователя (например, utmstack-ingest). Выберите программный доступ." + }, + "programmaticAccess": { + "title": "3 · Задать тип учётных данных", + "body": "Выберите \"Access key — Programmatic access\"." + }, + "attachPolicy": { + "title": "4 · Привязать политику чтения CloudWatch", + "body": "Привяжите управляемую AWS политику CloudWatchLogsReadOnlyAccess." + }, + "review": { + "title": "5 · Проверить пользователя", + "body": "Проверьте данные пользователя и нажмите Create user." + }, + "copyKeys": { + "title": "6 · Скопировать идентификатор ключа доступа и секрет", + "body": "Скопируйте Access key ID и Secret access key — секрет отображается только один раз." + }, + "createLogGroup": { + "title": "7 · Создать группу журналов CloudWatch", + "body": "В CloudWatch → Log groups создайте группу журналов с именем \"utmstack\" — другие интеграции AWS будут направлять данные в неё." + }, + "fillForm": { + "title": "8 · Заполнить форму", + "body": "Укажите в UTMStack ключ доступа, секрет, регион по умолчанию и имя группы журналов (например, \"utmstack\")." + }, + "activate": { + "title": "9 · Активировать", + "body": "Активируйте модуль UTMStack, чтобы начали поступать события AWS." + } + } + }, + "awsLambda": { + "sections": { + "iamPrerequisite": { + "title": "1 · Предварительное условие: IAM-пользователь", + "body": "Lambda использует модуль AWS IAM User — убедитесь, что эта интеграция настроена первой с политикой CloudWatchLogsReadOnlyAccess." + }, + "cloudwatchStream": { + "title": "2 · Lambda уже передаёт данные в CloudWatch Logs", + "body": "AWS Lambda автоматически публикует журналы выполнения в CloudWatch Logs в разделе /aws/lambda/. UTMStack получает данные из группы журналов, настроенной при создании IAM-пользователя." + }, + "activate": { + "title": "3 · Активировать", + "body": "Активируйте модуль UTMStack, чтобы начали поступать события Lambda." + } + } + }, + "awsSqlServer": { + "sections": { + "openRds": { + "title": "1 · Открыть консоль Amazon RDS", + "body": "Откройте https://console.aws.amazon.com/rds/." + }, + "pickDb": { + "title": "2 · Выбрать экземпляр БД", + "body": "На панели навигации выберите Databases и укажите экземпляр БД, который необходимо отслеживать." + }, + "modify": { + "title": "3 · Изменить экземпляр", + "body": "Выберите Modify." + }, + "logExports": { + "title": "4 · Включить экспорт журналов", + "body": "В разделе Log exports выберите Error log и Agent log для публикации в CloudWatch Logs." + }, + "apply": { + "title": "5 · Применить изменения", + "body": "Нажмите «Continue», затем «Modify DB Instance» на странице сводки." + }, + "activate": { + "title": "6 · Активировать", + "body": "Активируйте модуль UTMStack, чтобы начать получать события SQL Server." + } + } + }, + "awsPostgresql": { + "sections": { + "openRds": { + "title": "1 · Открыть консоль Amazon RDS", + "body": "Откройте https://console.aws.amazon.com/rds/." + }, + "pickDb": { + "title": "2 · Выбрать экземпляр БД", + "body": "На панели навигации выберите «Databases» и укажите экземпляр БД, который нужно изменить." + }, + "logExports": { + "title": "3 · Включить экспорт журналов", + "body": "В разделе «Log exports» выберите журнал PostgreSQL для публикации в CloudWatch Logs." + }, + "apply": { + "title": "4 · Применить изменения", + "body": "Нажмите «Continue», затем «Modify DB Instance» на странице сводки." + }, + "activate": { + "title": "5 · Активировать", + "body": "Активируйте модуль UTMStack, чтобы начать получать события PostgreSQL." + } + } + }, + "awsTrafficMirror": { + "sections": { + "createTarget": { + "title": "1 · Создать целевой объект зеркалирования трафика", + "body": "В консоли VPC создайте Traffic Mirror Target, указывающий на сетевой интерфейс виртуальной машины агента UTMStack." + }, + "createFilter": { + "title": "2 · Создать фильтр зеркалирования трафика", + "body": "Создайте Traffic Mirror Filter и добавьте правила входящего/исходящего трафика для протоколов, которые нужно зеркалировать (например, весь TCP, весь UDP)." + }, + "createSession": { + "title": "3 · Создать сессию зеркалирования трафика", + "body": "Создайте Traffic Mirror Session, связывающую каждый исходный сетевой интерфейс с созданными целевым объектом и фильтром." + }, + "iamPrerequisite": { + "title": "4 · Предварительное условие: пользователь IAM", + "body": "Убедитесь, что модуль AWS IAM User также настроен, чтобы UTMStack мог при необходимости читать журналы VPC Flow Logs." + }, + "activate": { + "title": "5 · Активировать", + "body": "Активируйте модуль UTMStack, чтобы начать разбор зеркалированного трафика." + } + } + }, + "forwarder": { + "intro": { + "title": "Принцип работы", + "body": "Журналы передаются от {{source}} в UTMStack Collector, который безопасно пересылает их в UTMStack для корреляции и оповещений. На {{source}} ничего не устанавливается — Collector достаточно запустить на одном из хостов вашей сети." + }, + "diagram": { + "sourceSub": "ваши журналы", + "forwarder": "Collector", + "forwarderSub": "слушает на {{port}}", + "utmstack": "UTMStack", + "utmstackSub": "оповещения и корреляция", + "flow1": "журналы", + "flow2": "защищённо" + }, + "noInstall": "На {{source}} ничего не устанавливается — нужно лишь перенаправить его журналы в Collector.", + "install": { + "title": "Установить UTMStack Collector", + "body": "Collector — это Linux-служба, которая принимает журналы с ваших устройств и отправляет их в UTMStack. Один Collector обрабатывает несколько интеграций одновременно.", + "reuse": "Collector уже запущен? Пропустите этот шаг — укажите {{source}} хост и порт существующего Collector, как показано ниже." + }, + "tls": { + "title": "Дополнительно — Включить шифрование TLS", + "intro": "По умолчанию прослушиватель принимает нешифрованный TCP/UDP. Чтобы зашифровать трафик syslog при передаче, сначала загрузите файлы сертификатов, затем повторно включите прослушиватель с протоколом tls.", + "step1": "1 · Загрузить сертификат и ключ (один раз на Collector)", + "step1Note": "Дополнительный сертификат CA можно передать третьим аргументом. Если его опустить, в роли CA будет использован конечный сертификат.", + "step2": "2 · Повторно включить прослушиватель с TLS" + }, + "httpsCerts": { + "title": "Загрузите TLS-сертификат на Collector", + "body": "Эта интеграция использует HTTPS-прослушиватель на порту {{port}}, поэтому перед её включением на Collector необходимо загрузить сертификат и ключ:" + }, + "uninstall": { + "title": "Дополнительно — Удалить Collector", + "body": "Выполните эту команду на хосте, где установлен Collector, чтобы остановить службу и удалить все её файлы." + }, + "instanceHeader": { + "title": "Заголовок авторизации", + "body": "Включайте этот заголовок Authorization в каждый запрос, отправляемый на инстанс. Секрет API-ключа отображается только один раз при его создании — скопируйте его тогда и вставьте вместо заполнителя ниже.", + "tabSimple": "Одиночный", + "tabBatch": "Пакетный" + }, + "manualCommand": { + "title": "Optional — Enable via the command line instead", + "intro": "Prefer the terminal? SSH into the Collector host and run the command below — it matches whatever protocol and port you have selected above.", + "certStep": "1 · Load your certificate and key (once per Collector)", + "enableStep": "2 · Enable the integration" + } + }, + "aix": { + "source": "Сервер AIX", + "step1": { + "title": "Включить прослушиватель AIX на Collector", + "body": "На хосте с установленным Collector выполните эту команду, чтобы открыть прослушиватель журналов AIX:", + "note": "Чтобы использовать TCP вместо UDP, замените udp на tcp в команде выше." + }, + "step2": { + "title": "Настроить AIX для пересылки журналов", + "body": "На вашей системе AIX настройте службу syslog для перенаправления журналов на хост Collector через порт {{port}}. Обратитесь к документации IBM за точным синтаксисом — он различается в зависимости от версии AIX." + } + }, + "deceptivebytes": { + "source": "Deceptive Bytes", + "step1": { + "title": "Включить прослушиватель Deceptive Bytes на Collector", + "body": "На хосте с установленным Collector выполните эту команду, чтобы открыть прослушиватель syslog Deceptive Bytes:", + "note": "Чтобы использовать TCP вместо UDP, замените udp на tcp в команде выше." + }, + "step2": { + "title": "Настроить Deceptive Bytes для пересылки журналов", + "body": "В консоли управления Deceptive Bytes настройте пересылку syslog для отправки событий на хост Collector через порт {{port}} (UDP). Deceptive Bytes генерирует syslog в формате CEF, который Collector принимает как тип данных deceptive-bytes." + } + }, + "mikrotik": { + "source": "Маршрутизатор MikroTik", + "step1": { + "title": "Включить прослушиватель MikroTik на Collector", + "body": "На хосте с установленным Collector выполните эту команду, чтобы открыть прослушиватель syslog MikroTik:", + "note": "Чтобы использовать TCP вместо UDP, замените udp на tcp в команде выше." + }, + "step2": { + "title": "Настроить MikroTik для пересылки журналов", + "body": "На маршрутизаторе MikroTik создайте удалённое действие журналирования (logging action), указывающее на хост Collector через порт {{port}}, и привяжите его к нужным темам журнала. Выполните следующее из CLI RouterOS (Terminal в Winbox):", + "note": "Также можно настроить через Winbox: System → Logging → вкладка Actions (добавить удалённое действие) → затем вкладка Rules (добавить правила, указывающие на новое действие)." + } + }, + "fortigate": { + "source": "Межсетевой экран FortiGate", + "step1": { + "title": "Включить прослушиватель FortiGate на Collector", + "body": "На хосте с установленным Collector выполните эту команду, чтобы открыть прослушиватель syslog FortiGate:", + "note": "Чтобы использовать TCP вместо UDP, замените udp на tcp в команде выше." + }, + "step2": { + "title": "Настроить FortiGate для пересылки журналов", + "body": "На FortiGate направьте syslog на хост Collector через порт {{port}}. Выполните следующее из CLI FortiOS (или используйте Log & Report → Log Settings → Syslog в GUI):", + "note": "Замените адрес сервера, если Collector запущен на другом хосте. Для нескольких коллекторов syslog используйте syslogd2/syslogd3/syslogd4." + } + }, + "fortiweb": { + "source": "FortiWeb WAF", + "step1": { + "title": "Включить прослушиватель FortiWeb на Collector", + "body": "На хосте с установленным Collector выполните эту команду, чтобы открыть прослушиватель syslog FortiWeb:", + "note": "Чтобы использовать TCP вместо UDP, замените udp на tcp в команде выше." + }, + "step2": { + "title": "Настроить FortiWeb для пересылки журналов", + "body": "На FortiWeb создайте политику syslog, указывающую на хост Collector через порт {{port}}, и включите журналирование syslog. Выполните следующее из CLI FortiWeb (или используйте Log & Report → Log Policy → Syslog Policy в GUI):", + "note": "Убедитесь, что в настройках Log & Report включена отправка нужных типов журналов (Attack, Event, Traffic) в syslog." + } + }, + "paloalto": { + "source": "Межсетевой экран Palo Alto", + "step1": { + "title": "Включить прослушиватель Palo Alto на Collector", + "body": "На хосте с установленным Collector выполните эту команду, чтобы открыть прослушиватель syslog Palo Alto:", + "note": "Чтобы использовать TCP вместо UDP, замените udp на tcp в команде выше." + }, + "step2": { + "title": "Создать профиль Syslog-сервера", + "body": "В PAN-OS перейдите в Device → Server Profiles → Syslog и добавьте профиль. Укажите адрес сервера {{host}}, транспорт UDP, порт {{port}} и формат BSD." + }, + "step3": { + "title": "Настроить пересылку журналов и выполнить Commit", + "body": "Создайте профиль Log Forwarding (Objects → Log Forwarding), который отправляет трафик, угрозы и другие типы журналов в указанный выше профиль syslog, привяжите его к правилам Security policy (Policies → Security → правило → Actions → Log Forwarding), затем выполните Commit." + } + }, + "pfsense": { + "source": "Межсетевой экран pfSense", + "step1": { + "title": "Включить прослушиватель pfSense на Collector", + "body": "На хосте с установленным Collector выполните эту команду, чтобы открыть прослушиватель syslog pfSense:", + "note": "Чтобы использовать TCP вместо UDP, замените udp на tcp в команде выше." + }, + "step2": { + "title": "Включить удалённое журналирование в pfSense", + "body": "В веб-интерфейсе pfSense перейдите в Status → System Logs → Settings. В разделе Remote Logging Options установите флажок Enable Remote Logging, укажите удалённый сервер журналов {{host}}:{{port}}, выберите журналы для отправки (или Everything) и нажмите Save." + } + }, + "sonicwall": { + "source": "Межсетевой экран SonicWall", + "step1": { + "title": "Включить прослушиватель SonicWall на Collector", + "body": "На хосте с установленным Collector выполните эту команду, чтобы открыть прослушиватель syslog SonicWall:", + "note": "Чтобы использовать TCP вместо UDP, замените udp на tcp в команде выше." + }, + "step2": { + "title": "Добавить Syslog-сервер в SonicOS", + "body": "В SonicOS перейдите в Device → Log → Syslog (на старых прошивках: Manage → Log → Syslog) и добавьте Syslog Server с адресом {{host}} и портом {{port}}. Установите Syslog Format в значение ArcSight (CEF) — UTMStack обрабатывает SonicWall в формате CEF — затем нажмите Apply." + } + }, + "sophosxg": { + "source": "Sophos Firewall", + "step1": { + "title": "Включить прослушиватель Sophos Firewall на Collector", + "body": "На хосте с установленным Collector выполните эту команду, чтобы открыть прослушиватель syslog Sophos Firewall:", + "note": "Чтобы использовать TCP вместо UDP, замените udp на tcp в команде выше." + }, + "step2": { + "title": "Добавить Syslog-сервер в Sophos Firewall", + "body": "В консоли Sophos Firewall (SFOS) перейдите в System → System services → Log settings и добавьте Syslog-сервер с адресом {{host}} и портом {{port}}. Выберите типы журналов для пересылки (firewall, IPS, ATP, web и др.) и нажмите Apply." + } + }, + "suricata": { + "source": "Suricata IDS", + "step1": { + "title": "Включить прослушиватель Suricata на Collector", + "body": "На хосте, где установлен Collector, выполните следующую команду для открытия прослушивателя Suricata:", + "note": "Чтобы использовать TCP вместо UDP, замените udp на tcp в приведённой выше команде." + }, + "step2": { + "title": "Отправить журналы Suricata EVE в syslog", + "body": "Suricata принимает данные в формате JSON (EVE). На хосте Suricata отредактируйте suricata.yaml и настройте вывод eve-log для записи в syslog:", + "note": "Затем перезапустите Suricata: sudo systemctl restart suricata" + }, + "step3": { + "title": "Пересылать syslog на Collector", + "body": "Направьте объект local5 (куда теперь пишет Suricata) на Collector. Добавьте это правило в /etc/rsyslog.d/60-utmstack-suricata.conf на хосте Suricata:", + "note": "Используйте @@ вместо @ для TCP. Затем перезапустите rsyslog: sudo systemctl restart rsyslog" + } + }, + "o365_graph": { + "intro": { + "title": "Как это работает", + "body": "UTMStack подключается к Microsoft 365 через зарегистрированное приложение Azure AD и опрашивает Microsoft Graph на события безопасности: оповещения, инциденты, аудит каталога, sign-in, обнаружения рисков, hunting-запросы и журналы аудита Purview. Агент в вашем tenant не устанавливается.", + "diagram": { + "source": "события безопасности", + "edge": "Microsoft Graph", + "utmstackSub": "корреляция и оповещения" + }, + "note": "UTMStack требует только доступа к API Graph в режиме чтения — разрешения на запись не запрашиваются." + }, + "appSection": "Регистрация приложения Azure", + "steps": { + "azurePortal": { + "title": "Откройте Microsoft Entra ID", + "body": "Откройте портал Azure (portal.azure.com) и нажмите Microsoft Entra ID." + }, + "appRegistrations": { + "title": "Перейдите к «Регистрации приложений»", + "body": "В левом меню нажмите Регистрация приложений." + }, + "registerApp": { + "title": "Зарегистрируйте новое приложение", + "body": "Нажмите Новая регистрация. Назовите его UTMStack Graph Dev, выберите Только учётные записи в этом организационном каталоге (Single-tenant) и нажмите Зарегистрировать." + }, + "clientSecret": { + "title": "Создайте секрет клиента", + "body": "Перейдите в Сертификаты и секреты → Новый секрет клиента. Добавьте описание, установите срок действия 730 дней (24 месяца) и нажмите Добавить.", + "copyNote": "Сразу скопируйте значение секрета — оно показывается только один раз и позже недоступно." + }, + "apiPermissions": { + "title": "Добавьте разрешения Microsoft Graph", + "body": "Перейдите в Разрешения API → Добавить разрешение и выберите Microsoft Graph, затем Разрешения приложения." + }, + "graphPermissions": { + "title": "Добавьте четыре разрешения Graph", + "body": "Добавьте SecurityEvents.Read.All, Directory.Read.All, AuditLog.Read.All и IdentityRiskEvent.Read.All." + }, + "adminConsent": { + "title": "Предоставьте согласие администратора", + "body": "Вернувшись в Разрешения API, нажмите Предоставить согласие администратора для {tenant} и подтвердите." + }, + "noteIds": { + "title": "Скопируйте идентификаторы приложения", + "body": "Перейдите в Обзор приложения и скопируйте Идентификатор приложения (клиента) и Идентификатор каталога (tenant). Также вам понадобится значение секрета, скопированное на шаге 4." + } + }, + "credentialsSection": "Учётные данные", + "credentials": { + "title": "Подключите ваш tenant Microsoft 365", + "body": "Введите данные из шагов выше. UTMStack проверяет учётные данные перед сохранением. Можно добавить несколько групп конфигурации." + }, + "fields": { + "tenantId": { + "label": "Идентификатор Tenant (Идентификатор каталога)" + }, + "clientId": { + "label": "Идентификатор клиента (Идентификатор приложения)" + }, + "clientSecret": { + "label": "Секрет клиента" + }, + "cloudEnv": { + "label": "Облачная среда (необязательно)", + "hint": "Commercial (по умолчанию), GCC, GCCHigh или DoD" + } + } + } + }, + "cloud": { + "howItWorksTitle": "Как это работает", + "howItWorksBody": "{{name}} работает полностью внутри UTMStack — нет необходимости развертывать агент или коллектор. Предоставьте учетные данные API только для чтения, и UTMStack будет извлекать события по расписанию, анализировать их и загружать в Log Explorer.", + "connectionTitle": "Соединение", + "noFields": "Не настроено ни одного поля соединения.", + "testConnection": "Проверить соединение", + "save": "Сохранить", + "afterTitle": "Что вы увидите после подключения", + "after1": "UTMStack выполняет первоначальную загрузку недавних событий.", + "after2": "Впоследствии события извлекаются каждые 1–5 минут (зависит от API).", + "after3": "Интеграция появляется в разделе Источники данных с текущим статусом извлечения и задержкой.", + "tenants": { + "title": "Настроенные группы конфигурации", + "empty": "Групп конфигурации пока нет. Добавьте первую ниже.", + "loading": "Загрузка групп конфигурации…", + "nameLabel": "Имя группы конфигурации", + "namePlaceholder": "напр. acme-prod", + "add": "Добавить группу конфигурации", + "update": "Обновить группу конфигурации", + "delete": "Удалить", + "edit": "Изменить", + "cancel": "Отмена", + "editing": "Редактирование: {{name}}", + "selectFile": "Выбрать файл", + "replaceFile": "Заменить файл", + "fileLoaded": "Файл загружен", + "invalidJson": "Не удалось прочитать файл как JSON.", + "createError": "Не удалось создать группу конфигурации. Повторите попытку.", + "updateError": "Не удалось обновить группу конфигурации. Повторите попытку.", + "createSuccess": "Группа конфигурации успешно создана.", + "updateSuccess": "Группа конфигурации успешно обновлена." + }, + "google": { + "sections": { + "createTopic": { + "title": "1 · Создайте тему Pub/Sub", + "body": "В консоли Google Cloud откройте Pub/Sub → Темы и создайте новую тему. UTMStack будет получать события через эту тему.", + "docLabel": "Открыть страницу тем Pub/Sub" + }, + "createSubscription": { + "title": "2 · Создайте подписку", + "body": "Внутри темы создайте подписку типа Pull. UTMStack извлекает сообщения из этой подписки." + }, + "configureSubscription": { + "title": "3 · Настройте подписку", + "body": "Задайте срок хранения сообщений в соответствии с допустимым простоем (по умолчанию 7 дней — это нормально). Оставьте срок подтверждения 10 секунд, а истечение — «Никогда»." + }, + "logsRouter": { + "title": "4 · Откройте Logs Router", + "body": "Перейдите в Logging → Logs Router и создайте новый sink. Он пересылает логи проекта в созданную выше тему Pub/Sub." + }, + "sinkDestination": { + "title": "5 · Направьте sink на тему", + "body": "Выберите Cloud Pub/Sub topic как назначение sink и выберите созданную тему. Используйте фильтры включения/исключения, чтобы ограничить, что пересылается." + }, + "serviceAccount": { + "title": "6 · Создайте сервисный аккаунт", + "body": "Откройте IAM и администрирование → Сервисные аккаунты и создайте новый сервисный аккаунт. Назначьте ему роль Pub/Sub Editor, чтобы UTMStack мог читать из подписки.", + "docLabel": "Открыть страницу сервисных аккаунтов" + }, + "serviceAccountKey": { + "title": "7 · Создайте ключ для сервисного аккаунта", + "body": "Откройте сервисный аккаунт, перейдите во вкладку Ключи и добавьте новый ключ. Выберите тип ключа JSON." + }, + "downloadKey": { + "title": "8 · Скачайте и загрузите JSON-ключ", + "body": "Сохраните JSON-файл, скачанный Google: его содержимое нужно вставить в поле «JSON-ключ сервисного аккаунта» ниже." + } + }, + "fields": { + "projectId": { + "label": "ID проекта" + }, + "subscription": { + "label": "Имя подписки" + }, + "jsonKey": { + "label": "JSON-ключ сервисного аккаунта" + } + }, + "intro": { + "title": "Принцип работы", + "body": "UTMStack считывает активность аудита непосредственно из Google Cloud через Pub/Sub. Маршрутизатор журналов направляет журналы проекта в тему Pub/Sub; UTMStack запускает внутренний сборщик, который читает Pull-подписку этой темы с помощью ключа сервисного аккаунта. В вашем GCP-проекте ничего не устанавливается.", + "diagram": { + "source": "Cloud Logging", + "edge1": "Logs Router", + "pubsub": "Pub/Sub", + "pubsubSub": "тема + подписка", + "edge2": "получает", + "utmstackSub": "оповещения и корреляция" + }, + "note": "В GCP агенты не запускаются — UTMStack получает сообщения из подписки Pub/Sub с помощью JSON-ключа сервисного аккаунта, который вы укажете ниже." + }, + "credentials": { + "title": "Конфигурация Pub/Sub", + "body": "Используйте собранные выше значения для настройки UTMStack. Вы можете отслеживать несколько проектов, сохранив дополнительные конфигурации.", + "mapping": { + "intro": "Справочник полей", + "projectId": "Project ID — GCP-проект, содержащий вашу тему, подписку и маршрутизатор журналов", + "subscription": "Имя подписки — Pull-подписка, созданная на шаге 2", + "jsonKey": "JSON-ключ сервисного аккаунта — файл, загруженный на шаге 8" + } + } + }, + "azure": { + "sections": { + "sharedAccessPolicy": { + "title": "2 · Добавьте политику общего доступа", + "body": "Откройте Event Hub → Политики общего доступа и создайте новую политику только с разрешением Listen." + }, + "connectionString": { + "title": "3 · Скопируйте основную строку подключения", + "body": "Откройте политику и скопируйте основную строку подключения. Она выглядит так: Endpoint=sb://...;SharedAccessKeyName=...;SharedAccessKey=..." + }, + "consumerGroup": { + "title": "4 · Создайте отдельную consumer group", + "body": "Откройте Event Hub → Consumer groups и создайте новую для UTMStack. Не используйте $Default — выделите UTMStack собственную группу, чтобы контрольные точки не пересекались с другими потребителями.", + "warn": "Создайте группу потребителей специально для UTMStack. Не используйте $Default или другие уже используемые группы — совместное использование группы потребителей несвязанными потребителями может привести к непредвиденному поведению и потере событий. Все экземпляры UTMStack должны использовать одну группу потребителей для совместной обработки событий." + }, + "storageContainer": { + "title": "6 · Создайте контейнер в учётной записи хранения", + "body": "В учётной записи хранения → Контейнеры создайте новый контейнер. Запишите имя контейнера и строку подключения учётной записи (Ключи доступа → Строка подключения)." + }, + "eventGrid": { + "title": "7 · Зарегистрируйте поставщик ресурсов Event Grid", + "body": "В Подписки → Поставщики ресурсов зарегистрируйте Microsoft.EventGrid, если ещё нет. Это позволит Azure пересылать события уровня подписки в ваш Event Hub." + }, + "createEventHub": { + "title": "Создать Event Hub", + "body": "На портале Azure создайте пространство имён Event Hubs и Event Hub внутри него. UTMStack будет считывать события из этого концентратора.", + "docLabel": "Краткое руководство: создание концентратора событий с помощью портала Azure" + }, + "createStorageAccount": { + "title": "Создать Storage Account", + "body": "UTMStack требуется Storage Account для сохранения контрольных точек позиции чтения. Создайте его в том же регионе, что и Event Hub.", + "docLabel": "Краткое руководство: создание учётной записи хранилища" + }, + "storageConnection": { + "title": "Скопировать строку подключения Storage Account", + "body": "Получите строку подключения Storage Account с ключом в разделе: All services → Storage accounts → ваша учётная запись → Access keys. UTMStack использует её для хранения контрольных точек Event Hub." + }, + "createEventSubscription": { + "title": "Создать подписку на события", + "body": "На панели Events подписки создайте новое событие, нажав Events → Event Subscription." + }, + "configureEventSubscription": { + "title": "Направить подписку на события в Event Hub", + "body": "Настройте подписку на события для отправки журналов в Event Hub, созданный на шаге 1." + } + }, + "fields": { + "eventHubConnection": { + "label": "Строка подключения Event Hub" + }, + "consumerGroup": { + "label": "Consumer group" + }, + "storageContainer": { + "label": "Имя контейнера хранения" + }, + "storageConnection": { + "label": "Строка подключения учётной записи хранения" + } + }, + "intro": { + "title": "Принцип работы", + "body": "UTMStack считывает активность аудита непосредственно из Azure Event Hub. Вы настраиваете подписку Azure для потоковой передачи событий в Event Hub; UTMStack запускает внутренний сборщик, который читает этот концентратор и сохраняет контрольные точки в Storage Account. В вашем тенанте Azure ничего не устанавливается.", + "diagram": { + "source": "события подписки", + "edge1": "передаёт в", + "eventHub": "Event Hub", + "eventHubSub": "поток событий", + "edge2": "получает", + "utmstackSub": "оповещения и корреляция" + }, + "note": "В Azure агенты не запускаются — UTMStack получает события из Event Hub с помощью строк подключения, которые вы укажете ниже." + }, + "sampleLabel": "Пример строки подключения:", + "credentials": { + "title": "Конфигурация Event Hub", + "body": "Используйте данные, собранные на предыдущих шагах, для настройки UTMStack. Вы можете добавить несколько Event Hub, сохранив дополнительные конфигурации.", + "mapping": { + "intro": "Справочник полей", + "eventHubConnection": "Строка подключения Event Hub — значение, полученное на шаге 3", + "consumerGroup": "Группа потребителей — значение, полученное на шаге 4", + "storageContainer": "Имя контейнера хранилища — значение, полученное на шаге 6", + "storageConnection": "Строка подключения учётной записи хранилища — значение, полученное на шаге 7" + } + } + }, + "aws": { + "fields": { + "accessKeyId": { + "label": "ID ключа доступа AWS" + }, + "secretAccessKey": { + "label": "Секретный ключ доступа AWS" + }, + "region": { + "label": "Регион AWS по умолчанию" + }, + "logGroupName": { + "label": "Имя log group" + } + }, + "intro": { + "title": "Принцип работы", + "body": "UTMStack считывает активность аудита непосредственно из AWS CloudWatch Logs. CloudTrail фиксирует вызовы API и события управления в вашем аккаунте AWS, пересылает их в группу журналов CloudWatch, а UTMStack опрашивает эту группу для приёма и корреляции событий.", + "diagram": { + "source": "события API", + "edge1": "CloudTrail", + "cloudwatchSub": "группы журналов", + "edge2": "опрашивает", + "utmstackSub": "оповещения и корреляция" + }, + "note": "На AWS агенты не устанавливаются — UTMStack получает события журналов с помощью учётных данных IAM с правами только на чтение, которые вы укажете ниже." + }, + "iamSection": "Настроить пользователя IAM", + "iam": { + "dashboard": { + "title": "Открыть панель управления IAM", + "body": "Откройте консоль AWS, перейдите на панель управления IAM и выберите Users." + }, + "addUser": { + "title": "Добавить пользователя", + "body": "Нажмите Add user, введите понятное имя пользователя и перейдите к следующему шагу." + }, + "attachPolicy": { + "title": "Прикрепить политику только для чтения", + "body": "В разделе Permissions прикрепите необходимую политику. Выберите CloudWatchLogsReadOnlyAccess для доступа только для чтения к CloudWatch." + }, + "createUser": { + "title": "Создать пользователя", + "body": "Проверьте конфигурацию и нажмите Create user для создания аккаунта." + }, + "openUser": { + "title": "Открыть нового пользователя", + "body": "Откройте только что созданного пользователя, щёлкнув по его имени, чтобы просмотреть сведения и управлять учётными данными." + }, + "securityTab": { + "title": "Перейти в раздел Security credentials", + "body": "Выберите вкладку Security credentials для создания ключей программного доступа." + }, + "createKey": { + "title": "Создать ключ доступа", + "body": "Нажмите Create access key и выберите вариант для приложения, работающего вне AWS (программный доступ)." + }, + "confirmKey": { + "title": "Подтвердить создание", + "body": "Подтвердите создание ключа доступа. AWS сгенерирует Access Key ID и Secret Access Key." + }, + "downloadKey": { + "title": "Сохранить учётные данные", + "body": "Загрузите файл с учётными данными или скопируйте Access Key ID и Secret Access Key в надёжное место — Secret Access Key отображается только один раз." + } + }, + "credentials": { + "title": "Ввести учётные данные", + "body": "Вставьте Access Key ID и Secret Access Key, полученные на предыдущих шагах. UTMStack проверяет учётные данные в AWS перед сохранением." + }, + "cloudwatchSection": "Настроить AWS CloudWatch", + "cloudwatch": { + "createGroup": { + "title": "Создать группу журналов CloudWatch", + "body": "Откройте консоль CloudWatch, выберите Log management и нажмите Create log group." + }, + "nameGroup": { + "title": "Задать имя группы журналов и срок хранения", + "body": "Введите имя группы журналов utmstack и установите срок хранения 1 day. Нажмите Create log group." + }, + "openTrail": { + "title": "Открыть CloudTrail и создать трейл", + "body": "В консоли CloudTrail нажмите Create trail, чтобы начать настройку нового трейла." + }, + "configureTrail": { + "title": "Настроить доставку, проверку и интеграцию с CloudWatch", + "body": "В форме создания CloudTrail задайте следующие параметры:", + "items": [ + "Trail name and scope: введите понятное имя; включите Apply trail to all accounts in my organization, если требуется сбор данных по всей организации.", + "S3 destination: выберите Create new S3 bucket (или укажите существующий бакет) для доставки необработанных журналов.", + "Encryption: включите Log file SSE-KMS и выберите подходящий KMS-ключ.", + "Log file validation: включите для обеспечения целостности доставляемых журналов (рекомендуется).", + "CloudWatch Logs: включите доставку в CloudWatch, выберите Use existing log group и введите точное имя utmstack.", + "IAM role: укажите или создайте роль, которую CloudTrail будет использовать для записи в S3 и публикации в CloudWatch." + ] + }, + "eventTypes": { + "title": "Выбрать типы событий", + "body": "Включите категории событий, необходимые для мониторинга и аудита.", + "management": { + "label": "1 · События управления", + "body": "Включите Management events и выберите All, чтобы записывать всю активность API, управляющую ресурсами AWS (создание, обновление, удаление)." + }, + "data": { + "label": "2 · События данных", + "body": "Добавьте Data event. Выберите S3 и укажите Log all events, чтобы фиксировать операции на уровне объектов, такие как GetObject и PutObject." + }, + "network": { + "label": "3 · События сетевой активности", + "body": "В разделе Network Activities добавьте хотя бы одну службу (например, ec2.amazonaws.com) и включите Log all events." + } + }, + "review": { + "title": "Проверьте и создайте трейл", + "body": "На экране Configure event aggregation примите значения по умолчанию (или измените при необходимости). Проверьте все настройки и нажмите Create trail." + } + } + }, + "crowdstrike": { + "intro": { + "title": "Как это работает", + "body": "UTMStack считывает обнаружения и активность аудита напрямую из CrowdStrike Falcon Event Streams API. Вы создаёте API-клиент в Falcon с областью Event Streams; UTMStack запускает внутренний пуллер, который получает события с использованием этих учётных данных. На ваших конечных точках или в Falcon ничего не устанавливается.", + "diagram": { + "source": "обнаружения и события", + "edge1": "Event Streams API", + "api": "Falcon API", + "apiSub": "поток событий", + "edge2": "получает", + "utmstackSub": "оповещения и корреляция" + }, + "note": "UTMStack не устанавливает агентов — он получает события из Falcon, используя предоставленные вами ниже учётные данные API-клиента (только чтение)." + }, + "sections": { + "apiClients": { + "title": "Откройте API Clients and Keys", + "body": "В консоли Falcon откройте меню (значок гамбургера, в верхнем левом углу) и перейдите в Support and resources → API Clients and Keys." + }, + "createClient": { + "title": "Создайте новый API-клиент", + "body": "Нажмите Create API Client, чтобы начать создание нового клиента." + }, + "scopes": { + "title": "Задайте имя клиента и назначьте область Event Streams", + "body": "Присвойте клиенту понятное имя (UTMStack использует его для идентификации источника событий) и выберите области API, необходимые для Event Streams. Нажмите Create для генерации учётных данных." + }, + "recordCredentials": { + "title": "Сохраните учётные данные", + "body": "Скопируйте Client ID, Client Secret и Base URL для вашего региона CrowdStrike. Секрет отображается только один раз — сохраните его в надёжном месте. Все три значения нужно будет вставить в форму ниже." + } + }, + "credentials": { + "title": "Конфигурация API-клиента", + "body": "Используйте учётные данные из шагов выше для настройки UTMStack. Вы можете добавить несколько клиентов CrowdStrike, сохранив дополнительные конфигурации.", + "mapping": { + "intro": "Описание полей", + "appName": "Имя приложения — понятное имя клиента из шага 3 (идентифицирует источник событий)", + "clientId": "Client ID — значение, сохранённое на шаге 4", + "clientSecret": "Client Secret — значение, сохранённое на шаге 4 (отображается только один раз)", + "cloudRegionUrl": "Base URL — конечная точка вашего региона, например https://api.crowdstrike.com (us-1), https://api.us-2.crowdstrike.com (us-2), https://api.eu-1.crowdstrike.com (eu-1)" + } + }, + "fields": { + "appName": { + "label": "Имя приложения" + }, + "clientId": { + "label": "Client ID" + }, + "clientSecret": { + "label": "Client Secret" + }, + "cloudRegionUrl": { + "label": "Base URL (облачный регион)" + } + } + } + }, + "custom": { + "whenTitle": "Когда это использовать", + "whenBody": "Когда ваш источник отсутствует в каталоге. Перенаправьте произвольный syslog или JSON в UTMStack и определите парсер для нормализации полей.", + "endpointsTitle": "Конечные точки", + "syslogUdp": "Syslog (UDP)", + "syslogTls": "Syslog (TLS)", + "httpJson": "HTTP / JSON", + "payloadTitle": "Пример payload JSON", + "parserTitle": "Определить парсер", + "parserBody": "Входящие события сохраняются под типом данных {{dataType}}. Добавьте фильтр разбора, чтобы необработанные данные сопоставлялись со структурированными полями, затем создавайте на их основе правила оповещений.", + "openEditor": "Открыть редактор парсера", + "powershellLabel": "PowerShell (запустить от имени администратора)", + "linuxLabel": "Linux — bash", + "macosLabel": "macOS — bash", + "exampleLabel": "Пример целевого syslog на {{name}}:", + "intro": { + "title": "Как это работает", + "body": "Пользовательская интеграция принимает журналы из любого источника, не охваченного встроенными модулями. Вы устанавливаете UTMStack Collector, регистрируете слушатель для ваших данных с выбранным протоколом и указываете источник на него.", + "note": "Выберите протокол, который может использовать ваш источник (syslog UDP/TCP/TLS или HTTP/HTTPS для JSON) ниже — Collector автоматически создаст тип данных." + }, + "diagram": { + "source": "Ваш источник", + "sourceSub": "любое приложение или устройство", + "forwarder": "Collector", + "ingests": "принимает", + "utmstackSub": "оповещения и корреляция" + }, + "choose": { + "title": "Выберите протокол и порт", + "body": "Выберите способ отправки данных источником и порт, на котором должен слушать Collector, затем выполните команду активации на хосте Collector.", + "portLabel": "Порт прослушивания", + "tlsFirst": "Сначала загрузите ваш TLS-сертификат и ключ на Collector:", + "enableLabel": "Затем включите интеграцию:", + "authNote": "Для включения аутентификации добавьте --auth bearer (токен) или --auth hmac — Collector выведет токен для использования в заголовке Authorization." + }, + "send": { + "title": "Направьте ваш источник на Collector", + "bodyNetwork": "Настройте ваш источник для отправки syslog {{proto}} на {{host}}:{{port}}. На большинстве устройств для этого есть параметр удалённого syslog или пересылки журналов.", + "bodyHttp": "Отправляйте события в формате JSON через HTTP POST на {{endpoint}}. Тело каждого запроса — одно событие JSON:", + "httpBindNote": "По умолчанию слушатель HTTP/HTTPS привязывается к 127.0.0.1 (хосту Collector), поэтому отправляйте запросы из приложения, работающего на этом хосте, или используйте обратный прокси. Для удалённых источников используйте syslog (UDP/TCP/TLS)." + }, + "manualCommand": { + "title": "Optional — Enable via the command line instead", + "intro": "Prefer the terminal? SSH into the Collector host and run the command below — it matches whatever protocol and port you have selected above." + } + }, + "remoteEnable": { + "title": "Включить эту интеграцию удалённо", + "body": "Выберите Collector, протокол и порт, затем включите интеграцию — SSH не требуется.", + "noPermission": "У вас нет прав на управление удалёнными интеграциями. Попросите администратора предоставить разрешение integrations.write.", + "loadingCollectors": "Загрузка Collectors…", + "noCollectors": "Ни один Collector ещё не зарегистрирован. Установите один выше, чтобы включить интеграции удалённо.", + "forwarderOffline": "Этот Collector находится в режиме офлайн и сейчас не может получать изменения конфигурации.", + "legendOnline": "{{count}} в сети", + "legendOffline": "{{count}} офлайн", + "legendTotal": "{{count}} всего", + "forwarderLabel": "Collector", + "protoLabel": "Протокол", + "portLabel": "Порт", + "currentStateLoading": "Проверка текущей конфигурации…", + "currentlyEnabled": "Сейчас: включено · {{proto}} · порт {{port}}", + "currentlyDisabled": "Сейчас: отключено · {{proto}} · порт {{port}}", + "authLabel": "Аутентификация", + "authNone": "Нет", + "authBearer": "Bearer-токен", + "authHmac": "HMAC-подпись", + "pathLabel": "Путь", + "signatureHeaderLabel": "Заголовок подписи", + "certTitle": "TLS-сертификат", + "certLoading": "Проверка статуса сертификата…", + "certLoaded": "Действительный сертификат уже загружен на этот Collector.", + "certMissing": "Сертификат ещё не загружен — загрузите один, чтобы включить этот протокол.", + "certInvalid": "Загруженный сертификат недействителен: {{error}}", + "certPemLabel": "Сертификат", + "keyPemLabel": "Закрытый ключ", + "caPemLabel": "Сертификат ЦА", + "uploadCertsButton": "Загрузить сертификат", + "certUploadSuccess": "Сертификат загружен.", + "certUploadError": "Не удалось загрузить сертификат.", + "certReadError": "Не удалось прочитать выбранный файл(ы).", + "enableButton": "Включить интеграцию", + "disableButton": "Отключить интеграцию", + "enableSuccess": "Интеграция включена.", + "disableSuccess": "Интеграция отключена.", + "enableError": "Не удалось обновить интеграцию.", + "secretWarning": "Сохраните этот токен в безопасном месте — он больше не будет показан.", + "sendToInstance": "Отправить на инстанс", + "enterpriseFeature": "Это функция Enterprise.", + "addCollector": "Добавить Collector", + "addApiKey": "Добавить API-ключ", + "apiKeyLabel": "API-ключ", + "apiKeyHint": "Сначала вам понадобится API-ключ.", + "apiKeyPlaceholder": "Выберите API-ключ", + "apiKeyAddNew": "Добавить API-ключ…", + "apiKeyNone": "Нет ни одного API-ключа", + "forwarderNoRemoteControl": "Этот форвардер установлен с отключённым удалённым управлением. Он игнорирует конфигурацию, отправленную отсюда; изменить это можно только на самой машине." + } + }, + "codeBlock": { + "copy": "Копировать", + "copied": "Скопировано" + }, + "createDrawer": { + "title": "Новая пользовательская интеграция", + "moduleName": "Имя модуля", + "moduleNameHint": "Уникальный идентификатор. Без пробелов.", + "moduleNamePlaceholder": "moya-custom-app", + "prettyName": "Отображаемое имя", + "prettyNamePlaceholder": "Moya Custom App", + "dataType": "Тип данных", + "dataTypePlaceholder": "Уникальный идентификатор для этого типа данных", + "icon": "Значок", + "iconHint": "PNG, SVG, JPEG, GIF или WEBP. Максимум 3 МБ. Используется как логотип интеграции.", + "iconPreview": "Предпросмотр значка", + "dataTypeExists": "Этот тип данных уже существует", + "invalidFileType": "Значок должен быть действительным файлом изображения (PNG, JPEG, SVG, GIF, WEBP)", + "fileTooLarge": "Значок не должен превышать 3 МБ", + "fileReadError": "Ошибка при чтении файла", + "cancel": "Отмена", + "create": "Создать интеграцию", + "creating": "Создание…", + "editTitle": "Редактировать интеграцию", + "save": "Сохранить", + "saving": "Сохранение…", + "currentIcon": "Текущий значок — загрузите файл для замены", + "name": "Название интеграции", + "namePlaceholder": "например, Acme Firewall", + "description": "Описание", + "descriptionPlaceholder": "Что принимает эта интеграция и зачем (необязательно)", + "identifierHint": "Сохраняется как “{{id}}” (производное от имени)", + "nameTaken": "Это название интеграции нельзя использовать — интеграция с таким идентификатором уже существует.", + "removeIcon": "Удалить значок", + "defaultIconNote": "Значок по умолчанию — загрузите файл, чтобы использовать собственный." + }, + "toast": { + "created": "Интеграция создана", + "updated": "Интеграция обновлена", + "updateError": "Не удалось обновить интеграцию" + }, + "delete": { + "title": "Удалить интеграцию", + "confirm": "Удалить эту интеграцию?", + "yes": "Удалить", + "no": "Отмена", + "deleted": "Интеграция удалена", + "error": "Не удалось удалить интеграцию" + }, + "modules": { + "WINDOWS_AGENT": "Сбор системной, защитной активности и журналов событий Windows через лёгкий агент UTMStack, установленный на каждом хосте.", + "LINUX_AGENT": "Сбор системных журналов, журналов аутентификации и аудита Linux через лёгкий агент UTMStack, установленный на каждом хосте.", + "MACOS": "Сбор системных журналов и журналов безопасности macOS с конечных точек Apple Mac через лёгкий агент UTMStack.", + "VMWARE": "Приём syslog гипервизора VMware ESXi для мониторинга активности и событий хостов виртуализации в UTMStack.", + "NETFLOW": "Приём записей NetFlow от маршрутизаторов и коммутаторов для мониторинга сетевого трафика и обнаружения аномалий.", + "AWS_IAM_USER": "Приём активности учётных записей AWS и вызовов API через CloudTrail и CloudWatch для аудита использования облака, доступа и изменений.", + "AZURE": "Приём журналов платформы и активности Microsoft Azure для мониторинга облачных нагрузок, удостоверений и изменений ресурсов.", + "O365": "Приём журналов аудита Microsoft 365 по Exchange, Teams, SharePoint и OneDrive для мониторинга активности пользователей и администраторов.", + "O365_GRAPH": "Захват событий безопасности Microsoft Graph — оповещения, инциденты, аудит каталога, sign-in, обнаружения рисков и журналы аудита Purview — для мониторинга идентификации и угроз в вашем tenant.", + "GCP": "Приём журналов аудита и активности Google Cloud Platform для мониторинга вычислений, хранилища и удостоверений в проектах.", + "KASPERSKY": "Приём обнаружений Kaspersky Security Center и телеметрии конечных точек для корреляции активности вредоносного ПО в сети.", + "ESET": "Приём обнаружений конечных точек ESET PROTECT и телеметрии для корреляции многоуровневой защиты от вредоносного ПО.", + "BITDEFENDER": "Приём обнаружений Bitdefender GravityZone и телеметрии конечных точек для корреляции угроз на корпоративных устройствах.", + "SENTINEL_ONE": "Приём обнаружений конечных точек SentinelOne и поведенческой телеметрии для масштабной корреляции и расследования угроз.", + "SOPHOS": "Приём обнаружений Sophos Central по конечным точкам, серверам, межсетевым экранам и электронной почте для корреляции угроз в одном месте.", + "CROWDSTRIKE": "Приём обнаружений конечных точек и рабочих нагрузок CrowdStrike Falcon для корреляции активности облачных угроз в UTMStack.", + "CISCO": "Приём журналов трафика, VPN и угроз межсетевого экрана Cisco ASA для мониторинга защиты периметра и доступа в UTMStack.", + "MERAKI": "Приём syslog межсетевого экрана и устройств безопасности Cisco Meraki для мониторинга управляемого из облака сетевого трафика и угроз.", + "FIRE_POWER": "Приём журналов Cisco Firepower NGFW и IPS для мониторинга попыток вторжения и угроз на периметре.", + "CISCO_SWITCH": "Приём syslog и телеметрии коммутаторов Cisco для мониторинга производительности сети, изменений конфигурации и безопасности.", + "FORTIGATE": "Приём журналов трафика и угроз Fortinet FortiGate NGFW для мониторинга защиты периметра и сетевой активности.", + "FORTIWEB": "Приём журналов WAF Fortinet FortiWeb для мониторинга атак на веб-приложения и защиты открытых сервисов и API.", + "SOPHOS_XG": "Приём журналов межсетевого экрана Sophos XG, включающих веб-фильтрацию, IPS и VPN, для мониторинга сетевого трафика и угроз.", + "PALO_ALTO": "Приём журналов трафика и угроз Palo Alto Networks NGFW для мониторинга использования приложений и защиты периметра.", + "SONIC_WALL": "Приём журналов трафика и угроз SonicWall NGFW для мониторинга защиты периметра и сетевой активности в UTMStack.", + "PFSENSE": "Приём журналов межсетевого экрана и маршрутизатора pfSense с унифицированным управлением угрозами для мониторинга сетевого трафика и угроз.", + "MIKROTIK": "Приём журналов межсетевого экрана, маршрутизации и беспроводной сети MikroTik RouterOS для мониторинга сетевой активности и конфигурации.", + "AIX": "Сбор системных журналов, журналов безопасности и аудита IBM AIX Unix для мониторинга активности на платформах IBM Power в UTMStack.", + "AS_400": "Сбор системных журналов и журналов аудита IBM AS/400 (IBM i) для мониторинга активности пользователей на платформах OS/400.", + "ORACLE": "Приём журналов аудита Oracle Database для мониторинга запросов, доступа и привилегированных операций в базах данных.", + "SURICATA": "Приём оповещений Suricata IDS/IPS и сетевых событий для обнаружения вторжений и вредоносного трафика в сети.", + "DECEPTIVE_BYTES": "Приём оповещений Deceptive Bytes от платформы активного обмана конечных точек для раннего выявления активности злоумышленников.", + "GITHUB": "Приём журналов аудита GitHub для мониторинга доступа к репозиториям, изменений кода и активности организации в целях безопасности исходного кода.", + "UTMSTACK": "Приём телеметрии UTMStack SIEM и XDR для мониторинга работоспособности платформы, внутренней активности и событий самоаудита.", + "NGINX": { + "name": "Nginx", + "description": "Приём журналов доступа и ошибок Nginx для мониторинга активности веб-сервера, трафика обратного прокси и запросов клиентов." + }, + "APACHE": { + "name": "Apache", + "description": "Приём журналов доступа и ошибок Apache HTTPD для мониторинга активности веб-сервера и запросов клиентов." + }, + "APACHE2": { + "name": "Apache2", + "description": "Приём журналов веб-сервера Apache2 (HTTPD) для мониторинга обработки запросов, ошибок и доступа на хостах Linux." + }, + "IIS": { + "name": "IIS", + "description": "Приём активности доступа и журналов Internet Information Services (IIS) для мониторинга веб-обслуживания Windows." + }, + "MYSQL": { + "name": "MySQL", + "description": "Приём активности журналов MySQL для мониторинга запросов, аутентификации и доступа к хранилищу данных." + }, + "POSTGRESQL": { + "name": "PostgreSQL", + "description": "Приём журналов PostgreSQL для мониторинга запросов, доступа и активности в ваших хранилищах данных." + }, + "MONGODB": { + "name": "MongoDB", + "description": "Приём активности журналов MongoDB для мониторинга доступа к документной базе данных, запросов и поведения приложения." + }, + "REDIS": { + "name": "Redis", + "description": "Приём активности журналов и телеметрии Redis для мониторинга использования хранилища данных в памяти и нагрузок в реальном времени." + }, + "ELASTICSEARCH": { + "name": "Elasticsearch", + "description": "Приём журналов Elasticsearch для мониторинга поискового и аналитического движка и его прикладных нагрузок." + }, + "LOGSTASH": { + "name": "Logstash", + "description": "Приём журналов конвейеров Logstash для мониторинга конвейера обработки данных и преобразования событий." + }, + "KIBANA": { + "name": "Kibana", + "description": "Приём журналов Kibana для мониторинга уровня визуализации и исследования данных и его использования." + }, + "KAFKA": { + "name": "Apache Kafka", + "description": "Приём журналов Apache Kafka для мониторинга конвейеров потоковой передачи в реальном времени, брокеров и потока сообщений." + }, + "NATS": { + "name": "NATS", + "description": "Приём журналов обмена сообщениями NATS для мониторинга шины сообщений, подключённости и доставки событий." + }, + "HAPROXY": { + "name": "HAProxy", + "description": "Приём журналов HAProxy для мониторинга балансировки нагрузки, прокси-трафика и доступности сети." + }, + "TRAEFIK": { + "name": "Traefik", + "description": "Приём журналов Traefik для мониторинга маршрутизации, балансировки нагрузки и прокси-трафика между нагрузками." + }, + "OSQUERY": { + "name": "osquery", + "description": "Приём журналов OsQuery для мониторинга состояния конечных точек, запросов и инвентаризации системы через SQL-подобные запросы." + }, + "SYSLOG": { + "name": "Syslog", + "description": "Отправляйте syslog (RFC 5424/3164) с любого устройства или приложения на конечную точку коллектора для централизованного приёма журналов." + }, + "JSON": { + "name": "JSON Input", + "description": "Отправляйте данные журналов в формате JSON на конечную точку приёма для структурированного сбора событий из приложений и сценариев." + }, + "WINDOWS_SQL_SERVER": { + "name": "SQL Server Event Logs", + "description": "Collect Microsoft SQL Server audit and event records through the Windows Event Log and UTMStack agent." + }, + "WINDOWS_FILE_AUDITING": { + "name": "Windows File Access Auditing", + "description": "Collect Windows file access audit events through the Windows Event Log and UTMStack agent." + }, + "ELASTICsearch": { + "name": "ELASTICsearch", + "description": "Ingesta los registros de Elasticsearch para monitorear el motor de búsqueda y análisis y sus cargas de trabajo de aplicación." + } + }, + "edit": { + "title": "Редактировать интеграцию" + }, + "allCategories": "Все категории", + "customOnly": "Пользовательские" }, - "actions": { - "edit": "Редактировать", - "editWithAi": "Изменить с помощью ИИ" + "datasources": { + "title": "Источники данных", + "total": "всего {{count}}", + "subtitle": "Агенты, интеграции и прямые источники, поставляющие события. Статус определяется по времени последнего появления источника.", + "connectSource": "Подключить источник", + "loading": "Загрузка источников данных…", + "loadFailed": "Не удалось загрузить источники данных.", + "retry": "Повторить", + "none": "Нет источников по этому фильтру.", + "ingestion": { + "title": "Поступление", + "received": "событий получено", + "none": "Нет поступлений за последние 24 часа.", + "ago24h": "24ч назад", + "now": "сейчас" + }, + "usage": { + "title": "Источники данных", + "ofUnlimited": "из неограниченного", + "ofLimit": "из {{limit}}", + "overLimit": "Превышен лицензионный лимит — данные сверх лимита под угрозой.", + "configured": "настроено" + }, + "tabs": { + "all": "Все", + "agent": "Агенты", + "puller": "Интеграции", + "direct": "Прямые", + "offline": "Офлайн" + }, + "toolbar": { + "searchPlaceholder": "Поиск по имени…", + "list": "Список", + "cards": "Карточки", + "refresh": "Обновить" + }, + "labels": { + "filteredBy": "Фильтр по label", + "add": "Добавить label…", + "addFirst": "Добавить label…", + "hint": "Введите label и нажмите Enter, чтобы добавить. Изменения сохраняются автоматически." + }, + "status": { + "live": "Активен", + "idle": "Неактивен", + "offline": "Офлайн" + }, + "kind": { + "agent": "Агент", + "puller": "Интеграция", + "direct": "Прямой" + }, + "cols": { + "source": "Источник", + "type": "Тип", + "status": "Статус", + "events24h": "События 24ч", + "lastSeen": "Последний раз" + }, + "time": { + "justNow": "только что", + "minutesAgo": "{{count}} мин назад", + "hoursAgo": "{{count}} ч назад", + "daysAgo": "{{count}} дн назад" + }, + "drawer": { + "loading": "Загрузка…", + "loadFailed": "Не удалось загрузить источник данных.", + "statsIdentity": "Статистика и идентификация", + "metadata": "Метаданные", + "labelsSection": "Labels", + "dangerZone": "Опасная зона", + "rows": { + "events24h": "События 24ч", + "lastSeen": "Последний раз", + "discovered": "Обнаружен", + "kind": "Тип источника", + "dataType": "Тип данных", + "ip": "IP", + "id": "ID" + }, + "dangerText": "Удаление убирает источник из реестра. Исторические события остаются доступны в Log Explorer; если источник продолжит присылать данные, он будет обнаружен заново.", + "delete": "Удалить источник", + "confirmDelete": "Подтвердить удаление", + "cancel": "Отмена", + "viewLogs": "Просмотр журналов", + "trend": "Тренд приёма данных", + "noTrend": "В этом окне события не получены", + "logGap": "Последнее событие {{since}} — возможен пропуск журналов" + }, + "toast": { + "labelsUpdated": "Labels обновлены", + "labelsFailed": "Не удалось обновить labels", + "deleted": "Источник удалён", + "deleteFailed": "Не удалось удалить" + }, + "sensitivity": { + "section": "Чувствительность актива", + "hint": "Бизнес-критичность (CIA, 0–3) этого актива. Алерты по его хосту/IP взвешиваются этими значениями.", + "saved": "Чувствительность обновлена", + "failed": "Не удалось обновить чувствительность", + "save": "Сохранить", + "confidentiality": "Конфиденциальность", + "integrity": "Целостность", + "availability": "Доступность", + "levels": { + "0": "Нет", + "1": "Низкая", + "2": "Средняя", + "3": "Высокая" + } + }, + "limitBanner": { + "title": "Превышен лимит источников данных.", + "message": "У вас {{count}} источников данных, но ваша лицензия покрывает {{limit}}. Журналы из источников сверх лимита отбрасываются.", + "cta": "Управление лицензией", + "dismiss": "Закрыть" + }, + "console": { + "section": "Консоль", + "sectionHint": "Выполняйте команды на этом хосте через его агент (живой отклик).", + "open": "Открыть консоль", + "close": "Закрыть", + "hint": "Введите команду и нажмите Enter, чтобы выполнить её на агенте.", + "running": "Выполнение…", + "placeholder": "Введите команду…", + "offline": "Похоже, этот агент офлайн — он может не отвечать на команды.", + "vars": { + "button": "Переменные", + "title": "Переменные команд", + "subtitle": "Ссылайтесь на них в командах как", + "add": "Новая переменная", + "name": "Имя", + "value": "Значение", + "description": "Описание", + "isSecret": "Секрет (зашифрован, скрыт в выводе)", + "secret": "секрет", + "secretHint": "Оставьте пустым, чтобы сохранить хранимое значение.", + "save": "Сохранить", + "cancel": "Отмена", + "edit": "Изменить", + "delete": "Удалить", + "loading": "Загрузка…", + "empty": "Переменных пока нет.", + "saved": "Переменная сохранена", + "deleted": "Переменная удалена", + "nameRequired": "Необходимо указать имя", + "loadError": "Не удалось загрузить переменные", + "saveError": "Не удалось сохранить переменную", + "deleteError": "Не удалось удалить переменную", + "insert": "Вставить", + "valueRequired": "Требуется значение" + }, + "disabled": "Агент офлайн — команды отключены", + "connError": "Ошибка соединения", + "cmdError": "Ошибка команды", + "shellSelect": "Тип оболочки", + "noRemoteControl": "Этот агент установлен с отключённым удалённым управлением. Он отклоняет команды, и изменить это можно только на самой машине.", + "noRemoteControlShort": "Удалённое управление на этом агенте отключено", + "password": { + "title": "Аутентификация", + "hint": "Пройдите аутентификацию для выполнения команд на этом агенте.", + "tfaPrompt": "Код: ", + "confirm": "ОК", + "cancel": "Отмена", + "authError": "Ошибка аутентификации", + "authHint": "Пройдите аутентификацию для выполнения команд на этом агенте.", + "authOk": "Аутентифицирован." + } + }, + "health": { + "online": "в сети", + "offline": "не в сети", + "total": "всего" + } }, - "refresh": { - "title": "Автообновление", - "options": { - "off": "Выкл", - "10s": "10 с", - "30s": "30 с", - "1m": "1 мин", - "5m": "5 мин", - "15m": "15 мин" - } + "timeRange": { + "quick": "Быстрые диапазоны", + "relative": "Относительный", + "absolute": "Абсолютный", + "last": "Последние", + "apply": "Применить", + "allTime": "Всё время", + "from": "С", + "to": "По", + "now": "сейчас", + "units": { + "minutes": "минут", + "hours": "часов", + "days": "дней", + "weeks": "недель", + "months": "месяцев" + }, + "presets": { + "15m": "Последние 15 минут", + "1h": "Последний час", + "6h": "Последние 6 часов", + "24h": "Последние 24 часа", + "7d": "Последние 7 дней", + "30d": "Последние 30 дней" + } }, - "editor": { - "editing": "Редактирование", - "addWidget": "Добавить виджет", - "save": "Сохранить", - "discard": "Отменить", - "newTitle": "Новый виджет", - "newSubtitle": "Выберите тип диаграммы и источник данных, настройте её визуально. SQL-запрос будет создан автоматически.", - "editTitle": "Редактирование виджета", - "editSubtitle": "Настройте определение диаграммы. Изменения будут применены везде, где используется этот виджет.", - "loading": "Загрузка виджета…", - "notFoundTitle": "Виджет не найден", - "notFoundSubtitle": "Возможно, она была удалена или у вас нет к ней доступа.", - "backToDashboard": "Вернуться к панели", - "chartType": { - "title": "Тип диаграммы" - }, - "chartTypes": { - "bar": { - "label": "Столбцы", - "description": "Сравнение значений по категориям." - }, - "line": { - "label": "Линия", - "description": "Тренды по упорядоченной оси." - }, - "area": { - "label": "Область", - "description": "Заполненная линия — подчёркивает объём." - }, - "pie": { - "label": "Круговая", - "description": "Доля от целого по категориям." - }, - "metric": { - "label": "Метрика", - "description": "Одиночное скалярное значение." + "alerts": { + "title": "Оповещения", + "matching": "{{count}} совпадений", + "subtitle": "Расставьте приоритеты по важному.", + "openNow": "открыто прямо сейчас.", + "view": { + "alerts": "Оповещения", + "overview": "Обзор" + }, + "toolbar": { + "searchPlaceholder": "Поиск по имени оповещения…", + "allSeverities": "Все уровни серьёзности", + "export": "Экспорт в CSV", + "refresh": "Обновить" + }, + "severity": { + "high": "Высокий", + "medium": "Средний", + "low": "Низкий" + }, + "status": { + "open": "Открыто", + "in_review": "На проверке", + "completed": "Завершено", + "auto": "Автоматическая проверка" + }, + "statusTabs": { + "all": "Все" + }, + "overview": { + "overTime": "Оповещения по времени", + "matchingAlerts": "совпадающих оповещений", + "noData": "Нет данных.", + "bySeverity": "По серьёзности", + "byStatus": "По статусу" + }, + "filters": { + "add": "Добавить фильтр", + "clearAll": "Очистить всё", + "filterValues": "Фильтровать значения…", + "loadingValues": "Загрузка значений…", + "noValues": "Значения не найдены.", + "pickValue": "Выберите значение, чтобы добавить фильтр.", + "empty": "(пусто)", + "cancel": "Отмена", + "addBtn": "Добавить" + }, + "ops": { + "CONTAIN": "содержит", + "IS": "равно", + "IS_NOT": "не равно", + "EXIST": "существует", + "DOES_NOT_EXIST": "не существует" + }, + "fields": { + "adversary_domain": "Домен противника", + "adversary_geolocation_asn": "ASN противника", + "adversary_geolocation_aso": "ASO противника", + "adversary_geolocation_country": "Страна противника", + "adversary_host": "Хост противника", + "adversary_ip": "IP противника", + "adversary_url": "URL противника", + "adversary_user": "Пользователь противника", + "assignee": "Назначено", + "category": "Категория", + "dataSource": "Сенсор", + "dataType": "Тип данных", + "description": "Описание", + "id": "ID", + "impactScore": "Риск", + "impact_availability": "Доступность", + "impact_confidentiality": "Конфиденциальность", + "impact_integrity": "Целостность", + "incidentDetail_incidentName": "Название инцидента", + "incidentDetail_incidentId": "ID инцидента", + "isIncident": "Инцидент", + "name": "Название оповещения", + "notes": "Заметки", + "severity": "Серьёзность", + "status": "Статус", + "tags": "Теги", + "target_domain": "Домен цели", + "target_geolocation_asn": "ASN цели", + "target_geolocation_aso": "ASO цели", + "target_geolocation_country": "Страна цели", + "target_host": "Хост цели", + "target_ip": "IP цели", + "target_url": "URL цели", + "target_user": "Пользователь цели", + "technique": "Техника" + }, + "tagFilter": { + "tags": "Теги", + "tag_one": "{{count}} тег", + "tag_few": "{{count}} тега", + "tag_many": "{{count}} тегов", + "tag_other": "{{count}} тега", + "clearSelection": "Очистить выбор", + "noTags": "Нет тегов" + }, + "bulk": { + "selected": "Выбрано: {{count}}", + "setStatus": "Задать статус", + "addTag": "Добавить тег", + "noTags": "Нет тегов", + "addToIncident": "Добавить в инцидент", + "clear": "Очистить" + }, + "tagEditor": { + "tag": "Тег", + "noTagsYet": "Тегов пока нет", + "createTag": "Создать тег", + "newTagName": "Имя нового тега…", + "createApply": "Создать и применить тег", + "save": "Сохранить", + "cancel": "Отмена", + "edit": "Изменить тег", + "delete": "Удалить тег", + "systemLocked": "Системный тег (заблокирован)", + "alreadyExists": "Такой тег уже существует.", + "color": "Цвет {{color}}", + "createRule": "Создать правило тегирования с этим тегом" }, "table": { - "label": "Таблица", - "description": "Агрегированные строки." + "actions": "Действия", + "alert": "Оповещение", + "status": "Статус", + "technique": "Техника", + "severity": "Серьёзность", + "risk": "Риск", + "echoes": "Эхо", + "time": "Время", + "riskHint": "Оценка риска (0–100), окрашена по серьёзности", + "source": "Источник", + "adversary": "Противник" + }, + "row": { + "createRuleFromAlert": "Создать тег из этого оповещения", + "createIncident": "Создать инцидент из этого оповещения", + "viewIncident": "Показать детали инцидента", + "assignedTo": "Назначено: {{user}}", + "echoesTooltip": "{{count}} эхо — нажмите для развёртывания", + "echoesEmpty": "Эхо не зарегистрировано" + }, + "echoes": { + "title": "{{count}} эхо", + "close": "Закрыть", + "empty": "Для этого оповещения нет зарегистрированных эхо.", + "loadError": "Не удалось загрузить эхо." }, "list": { - "label": "Список", - "description": "Исходные строки без агрегации." + "loading": "Загрузка оповещений…", + "loadError": "Не удалось загрузить оповещения.", + "retry": "Повторить", + "empty": "Нет оповещений, соответствующих этому виду." + }, + "badge": { + "incident": "Инцидент", + "aiAssessed": "Оценено ИИ" + }, + "drawer": { + "setStatus": "Задать статус", + "completeFalsePositive": "Завершить + ложное срабатывание", + "addToIncident": "Добавить в инцидент", + "partOfIncident": "Часть инцидента", + "tabs": { + "summary": "Сводка", + "parties": "Стороны", + "events": "События", + "history": "История" + }, + "section": { + "description": "Описание", + "solution": "Решение", + "references": "Ссылки", + "details": "Подробности", + "yourNotes": "Ваши заметки", + "notes": "Заметки" + }, + "details": { + "severity": "Серьёзность", + "risk": "Риск", + "category": "Категория", + "technique": "Техника", + "sensor": "Сенсор", + "dataType": "Тип данных", + "alertId": "ID оповещения", + "statusNote": "Примечание к статусу", + "assignee": "Исполнитель" + }, + "incidentDetail": { + "incident": "Инцидент", + "id": "ID", + "createdBy": "Создал", + "created": "Создано" + }, + "notesPlaceholder": "Добавьте заметки по расследованию…", + "saveNotes": "Сохранить заметки", + "assignee": "Назначить", + "assign": "Назначить", + "unassign": "Снять назначение", + "unassigned": "Не назначено", + "loadingUsers": "Загрузка пользователей…", + "observationLabel": "Наблюдение", + "observationPlaceholder": "Добавить наблюдение…", + "cancel": "Отмена", + "continue": "Продолжить" + }, + "related": { + "sample": "Выборка до ~11 событий, которые движок сохранил для этого оповещения. Используйте «Показать все связанные журналы» для полного набора без ограничений.", + "loadingEchoes": "Загрузка событий его эхо…", + "sampleWithEchoes": "События, сохранённые в этом оповещении и в его {{count}} эхо (прочитано {{read}}). Используйте «Показать все связанные журналы» для полного набора без ограничений.", + "empty": "Для этого оповещения нет сохранённых событий-образцов. Загрузите полный коррелированный набор в Обозревателе журналов.", + "viewAll": "Показать все связанные журналы" + }, + "party": { + "source": "Источник / цель", + "adversary": "Противник", + "noData": "Нет данных.", + "ip": "IP", + "host": "Хост", + "user": "Пользователь", + "domain": "Домен", + "country": "Страна" + }, + "history": { + "empty": "История не записана.", + "by": "пользователь {{user}}", + "actions": { + "UPDATE_STATUS": "Статус обновлён", + "UPDATE_TAGS": "Теги обновлены", + "UPDATE_NOTES": "Заметки обновлены", + "UPDATE_SOLUTION": "Решение обновлено", + "MARK_AS_INCIDENT": "Отмечено как инцидент" + }, + "detail": { + "statusTo": "Статус → {{status}}", + "tags": "Теги: {{tags}}", + "aiAdded": "Добавлена оценка ИИ", + "observationAdded": "Добавлено наблюдение", + "notesUpdated": "Заметки обновлены" + } + }, + "ai": { + "title": "Оценка ИИ SOC", + "risk": "риск: {{risk}}", + "score": "{{score}}/100", + "generate": "Создать сводку ИИ", + "hint": "SOC-AI исследует это оповещение и добавит оценку.", + "generating": "Анализ оповещения… это может занять минуту.", + "ready": "Сводка ИИ готова", + "failed": "Не удалось создать сводку ИИ", + "slow": "Сводка ИИ формируется дольше ожидаемого. Она появится в оповещении, когда будет готова." }, - "region_map": { - "label": "Карта координат", - "description": "Размещение меток на карте мира по координатам широты и долготы." + "incident": { + "titleAdd_one": "Добавить {{count}} оповещение в инцидент", + "titleAdd_few": "Добавить {{count}} оповещения в инцидент", + "titleAdd_many": "Добавить {{count}} оповещений в инцидент", + "titleAdd_other": "Добавить {{count}} оповещений в инцидент", + "new": "Новый инцидент", + "existing": "Существующий инцидент", + "nameLabel": "Название инцидента", + "namePlaceholder": "напр. Предполагаемое вторжение Scattered Spider", + "descriptionLabel": "Описание", + "descriptionPlaceholder": "Необязательное краткое описание…", + "pickLabel": "Выберите инцидент", + "loading": "Загрузка…", + "selectPlaceholder": "Выберите инцидент…", + "willLink_one": "Будет связано {{count}} оповещение.", + "willLink_few": "Будут связаны {{count}} оповещения.", + "willLink_many": "Будут связаны {{count}} оповещений.", + "willLink_other": "Будут связаны {{count}} оповещений.", + "cancel": "Отмена", + "create": "Создать инцидент", + "add": "Добавить в инцидент" }, - "text": { - "label": "Текст", - "description": "Свободный текст или построчный вывод." + "toast": { + "statusUpdated": "Статус обновлён", + "statusFailed": "Не удалось обновить статус", + "tagsUpdated": "Теги обновлены", + "tagsFailed": "Не удалось обновить теги", + "tagCreateFailed": "Не удалось создать тег", + "tagUpdated": "Тег обновлён", + "tagUpdateFailed": "Не удалось обновить тег", + "tagDeleted": "Тег удалён", + "tagDeleteFailed": "Не удалось удалить тег", + "notesSaved": "Заметки сохранены", + "notesFailed": "Не удалось сохранить заметки", + "exportFailed": "Не удалось экспортировать CSV", + "noRelatedLogs": "Связанные журналы для этого оповещения не найдены", + "relatedLogsFailed": "Не удалось загрузить связанные журналы", + "incidentCreated": "Инцидент создан", + "alertsAdded": "Оповещения добавлены в инцидент", + "incidentFailed": "Не удалось сохранить инцидент", + "assigned": "Оповещение назначено", + "unassigned": "Назначение снято", + "assignFailed": "Не удалось обновить исполнителя", + "newAlertsToast_title": "Новые алерты", + "newAlertsToast_count_one": "{{count}} новый алерт", + "newAlertsToast_count_few": "{{count}} новых алерта", + "newAlertsToast_count_many": "{{count}} алертов", + "newAlertsToast_count_other": "{{count}} алерта", + "newAlertsToast_view": "Смотреть" } - }, - "dataSource": { - "title": "Какие данные?", - "dataset": "Набор данных", - "noDatasetHint": "Выберите набор данных, чтобы включить условия и группировку." - }, - "widgetTitle": { - "label": "Заголовок", - "placeholder": "Необязательно — по умолчанию тип диаграммы" - }, - "dataset": { - "placeholder": "Выберите набор данных…", - "loading": "Загрузка наборов данных…" - }, - "filters": { - "title": "Включать только события, где…", - "empty": "Без условий — включаются все события за выбранный период.", - "add": "Добавить условие", - "remove": "Удалить", - "field": "Поле", - "fieldPlaceholder": "напр. host.name", - "operator": "Оператор", - "value": "Значение", - "valuePlaceholder": "Значение", - "from": "От", - "to": "До", - "noValue": "Значение не требуется", - "listPlaceholder": "Значения через запятую" - }, - "operators": { - "IS": "равно", - "IS_NOT": "не равно", - "IS_ONE_OF_TERMS": "одно из", - "IS_GREATER_THAN": "больше чем", - "IS_LESS_THAN_OR_EQUALS": "меньше или равно", - "IS_BETWEEN": "в диапазоне", - "CONTAIN": "содержит", - "DOES_NOT_CONTAIN": "не содержит", - "START_WITH": "начинается с", - "ENDS_WITH": "заканчивается на", - "EXIST": "существует", - "DOES_NOT_EXIST": "не существует" - }, - "dimension": { - "title": "Группировать по", - "field": "Поле", - "placeholder": "Выберите поле для группировки…" - }, - "table": { - "hint": "Показывает все поля записей. Добавьте столбцы, чтобы выбрать нужные.", - "columnsTitle": "Столбцы", - "allColumns": "Будут показаны все столбцы. Добавьте поля, чтобы выбрать конкретные.", - "addColumn": "Добавить столбец…", - "removeColumn": "Удалить столбец" - }, - "chartPreview": { - "title": "Предпросмотр диаграммы", - "noQuery": "Выберите набор данных, чтобы увидеть предпросмотр.", - "error": "Запрос предпросмотра завершился ошибкой." - }, - "chartTypeChip": { - "label": "Диаграмма:" - }, - "chartTypeModal": { - "title": "Выберите тип диаграммы", - "subtitle": "Выберите способ визуализации данных. Это можно изменить позже.", - "confirm": "Продолжить", - "swapTitle": "Изменить тип диаграммы", - "swapConfirm": "Применить" - }, - "saveVisualization": "Сохранить виджет", - "fieldSelect": { - "loading": "Загрузка полей…", - "choose": "Выберите поле…" - }, - "toast": { - "notReady": "Перед сохранением выберите набор данных и поле для разбивки." - }, - "breakdown": { - "title": "Разбивка по", - "time": "По времени", - "field": "Частые значения", - "interval": "Размер интервала", - "intervalAuto": "Автоматически", - "limit": "Сколько", - "limitPlaceholder": "По умолчанию (50)", - "splitHint": "Необязательно: по одной линии на каждое значение поля.", - "topValuesTable": "Tabla de valores principales" - }, - "editFilters": "Edit filters" - }, - "grid": { - "empty": "В этой панели пока нет виджетов.", - "missingVisualization": "Виджет недоступен", - "unknownVisualization": "Виджет" - }, - "widget": { - "renderError": "Не удалось отобразить этот виджет.", - "loading": "Загрузка данных…", - "queryError": "Не удалось загрузить данные виджета.", - "noData": "Нет данных за выбранный диапазон времени.", - "regionMapEmpty": "Нет точек с корректными широтой/долготой.", - "regionMapShapeHint": "SQL должен возвращать столбцы широты и долготы (или массив value [lat, lon, count]).", - "regionMapUnnamed": "(без названия)", - "regionMapValue": "значение: {{value}}", - "editAriaLabel": "Редактировать виджет", - "removeAriaLabel": "Удалить виджет", - "moveBack": "Переместить назад", - "moveForward": "Переместить вперёд", - "width": "Ширина", - "height": "Высота", - "widthSmall": "1 стлб", - "widthMedium": "2 стлб", - "widthLarge": "3 стлб", - "heightNormal": "Обычная", - "heightTall": "Высокая", - "incompleteSpec": "В этом виджете не хватает части вопроса.", - "count": "Conteo" - }, - "form": { - "createTitle": "Новая панель", - "renameTitle": "Редактировать панель", - "name": "Название", - "namePlaceholder": "напр. Обзор сети", - "description": "Описание", - "descriptionPlaceholder": "Необязательно", - "cancel": "Отмена", - "create": "Создать", - "save": "Сохранить" - }, - "confirm": { - "deleteTitle": "Удалить панель", - "delete": "Удалить панель «{{name}}»? Это действие нельзя отменить.", - "deleteWidgetsTitle": "Удалить виджеты", - "deleteWidgets_one": "Удалить этот виджет? Это действие нельзя отменить.", - "deleteWidgets_other": "Удалить виджетов: {{count}}? Это действие нельзя отменить.", - "dismissTitle": "Убрать панель", - "dismiss": "Удалить панель по умолчанию «{{name}}»? Позже вы сможете создать новую на её основе через «Создать» → «На основе существующего»." - }, - "page": { - "noSelection": "Выберите панель из списка или создайте новую, чтобы начать.", - "loading": "Загрузка виджетов…" - }, - "toast": { - "created": "Панель создана.", - "createFailed": "Не удалось создать панель.", - "updated": "Панель обновлена.", - "updateFailed": "Не удалось обновить панель.", - "deleted": "Панель удалена.", - "deleteFailed": "Не удалось удалить панель.", - "layoutSaved": "Макет сохранён.", - "layoutSaveFailed": "Не удалось сохранить макет.", - "visualizationCreated": "Виджет создан.", - "visualizationCreateFailed": "Не удалось создать виджет.", - "visualizationUpdated": "Виджет обновлён.", - "visualizationUpdateFailed": "Не удалось обновить виджет.", - "visualizationDeleted": "Виджет удалён.", - "visualizationDeleteFailed": "Не удалось удалить виджет.", - "filterCreated": "Фильтр создан.", - "filterUpdated": "Фильтр обновлён.", - "filterDeleted": "Фильтр удалён.", - "filterCreateFailed": "Не удалось создать фильтр.", - "filterUpdateFailed": "Не удалось обновить фильтр.", - "filterDeleteFailed": "Не удалось удалить фильтр.", - "filtersSaved": "Filters saved.", - "filtersSaveFailed": "Could not save filters." - }, - "newDashboard": { - "title": "Новая панель", - "subtitle": "Создайте пустую панель. Виджеты можно добавить после сохранения.", - "modeManual": "Создать вручную", - "modeAi": "С помощью ИИ", - "aiLocked": "Включите SOC-AI и настройте его, чтобы использовать эту функцию.", - "aiDescriptionLabel": "Что должна показывать эта панель?", - "aiDescriptionPlaceholder": "например, Неудачные входы по странам, последние 7 дней", - "aiCreate": "Создать с помощью ИИ", - "aiOpenerWithDetails": "Создай панель с названием «{{name}}», показывающую: {{description}}" - }, - "newVisualization": { - "title": "Новый виджет", - "subtitle": "Определите переиспользуемую диаграмму из SQL-запроса и конфигурации ECharts.", - "sqlQuery": "SQL-запрос", - "sqlQueryPlaceholder": "SELECT bucket, count(*) FROM logs GROUP BY bucket", - "sqlQueryHint": "Используйте плейсхолдеры timeFilter, from и to (в двойных фигурных скобках), чтобы выбор времени применялся при рендеринге.", - "config": "Конфигурация диаграммы (опция ECharts, JSON)", - "configHint": "Должен быть корректный JSON. Строки SQL доступны как `dataset.source` — свяжите серии через `encode`.", - "configError": "Некорректный JSON: {{error}}" - }, - "visualizationList": { - "title": "Виджеты", - "subtitle": "Доступно виджетов: {{count}}.", - "subtitleFiltered": "Показано {{shown}} из {{total}}.", - "create": "Создать", - "searchPlaceholder": "Поиск виджетов…", - "loading": "Загрузка виджетов…", - "empty": "Виджетов пока нет.", - "emptyFiltered": "Нет виджетов, соответствующих текущим фильтрам.", - "delete": "Удалить", - "deleteTitle": "Удалить виджет", - "confirmDelete": "Удалить виджет «{{name}}»? Это действие нельзя отменить.", - "filters": { - "search": "Поиск", - "chartType": "Тип диаграммы", - "allChartTypes": "Все типы диаграмм", - "source": "Источник", - "allSources": "Все источники", - "createdAt": "Создана", - "modifiedAt": "Изменена", - "createdRangeTitle": "Произвольный диапазон — Создание", - "modifiedRangeTitle": "Произвольный диапазон — Изменение", - "pickRange": "Выбрать диапазон", - "datePresets": { - "all": "Всё время", - "today": "Сегодня", - "last7": "За 7 дней", - "last30": "За 30 дней", - "lastYear": "За год", - "custom": "Произвольный" - }, - "clear": "Сбросить фильтры" - }, - "col": { - "name": "Название", - "chartType": "Тип диаграммы", - "source": "Источник", - "description": "Описание", - "created": "Создана", - "modified": "Изменена" - } - }, - "tabs": { - "dashboards": "Дашборды", - "visualizations": "Виджеты", - "newDashboard": "Новый дашборд", - "unsetDefault": "Убрать по умолчанию", - "options": "Параметры" - }, - "picker": { - "none": "Выбрать дашборд", - "search": "Поиск дашбордов…", - "new": "Новый дашборд", - "setDefault": "Сделать по умолчанию", - "empty": "Нет дашбордов" - }, - "empty": { - "title": "Дашбордов пока нет", - "body": "Создайте первый дашборд, чтобы видеть данные безопасности с одного взгляда.", - "cta": "Создать дашборд" - }, - "filters": { - "addTitle": "Добавить фильтр", - "editTitle": "Изменить фильтр", - "removeTitle": "Удалить фильтр", - "removeConfirm": "Удалить фильтр «{{label}}»? Это действие нельзя отменить.", - "remove": "Удалить", - "editAria": "Изменить фильтр", - "removeAria": "Удалить фильтр", - "saving": "Сохранение…", - "addChip": "Добавить фильтр", - "chooseValue": "Choose…", - "selected": "selected", - "loading": "Loading values…", - "searchPlaceholder": "Search values…", - "noValues": "No values available.", - "loadError": "Could not load values.", - "clear": "Clear", - "editorTitle": "Dashboard filters", - "editorHint": "Add dropdown chips that filter every widget on this dashboard.", - "emptyEditor": "No filter chips yet. Add one to get started.", - "cancel": "Cancel", - "save": "Save", - "field": { - "dataset": "Data set", - "field": "Field", - "chooseField": "Choose a field…", - "label": "Label", - "labelPlaceholder": "e.g. Host", - "placeholder": "Placeholder", - "placeholderPlaceholder": "e.g. Pick a host", - "multiple": "Multiple", - "searchable": "Searchable" - } }, - "duplicate": { - "copyName": "{{name}} (копия)" - } - }, - "settings": { - "title": "Настройки", - "license": "Лицензия", - "notifications": "Уведомления", - "connectionKey": "Ключ подключения", - "dataRetention": "Хранение данных", - "indices": "Индексы", - "theme": "Тема", - "apiKeys": "API-ключи", - "identityProviders": "Поставщики удостоверений", - "email": "Настройка эл. почты", - "dateFormat": "Формат даты", - "auditLogs": "Журнал аудита", - "about": "О системе", - "branding": "Брендинг", - "language": "Язык", - "socAi": "SOC-AI", - "supportAccess": "Доступ поддержки", - "threatwinds": "Интеграция ThreatWinds" - }, - "topbar": { - "theme": { - "light": "Светлая тема", - "dark": "Тёмная тема" + "dataProcessing": { + "live": { + "auto": "Авто" + }, + "pipeline": { + "title": "Конвейер приёма", + "stages": { + "received": "Получено", + "parsed": "Разобрано", + "analyzed": "Проанализировано", + "stored": "Сохранено" + } + }, + "kpi": { + "stored": "Сохранено", + "throughput": "Пропускная способность", + "perMin": "{{value}}/мин", + "survival": "{{rate}}% сохранено", + "received": "Получено", + "dropped": "Отброшено", + "dropRate": "{{rate}}% отброшено" + }, + "chart": { + "title": "Пропускная способность во времени", + "received": "Получено", + "dropped": "Отброшено" + }, + "donut": { + "title": "Состав отбрасывания", + "dropped": "отброшено" + }, + "breakdown": { + "title": "Топ источников и типов", + "bars": "Столбцы", + "treemap": "Treemap", + "showAll": "Показать все {{count}}", + "showLess": "Показать меньше", + "lastSeen": "Последний раз", + "ago": "{{time}} назад" + }, + "title": "Обработка данных", + "subtitle": "Статистика приёма и обработки: полученные события, отброшенные на этапах, а также основные источники и типы.", + "ingestion": { + "title": "Приём данных", + "last24h": "за последние 24 часа", + "noData": "Нет данных в этом окне.", + "loadError": "Не удалось загрузить статистику приёма.", + "groupBy": { + "dataSource": "По источнику данных", + "dataType": "По типу данных" + }, + "status": { + "received": "Получено", + "parsing_dropped": "Отброшено (разбор)", + "analysis_dropped": "Отброшено (анализ)", + "correlation_dropped": "Отброшено (корреляция)", + "all": "Все события" + } + }, + "filters": { + "title": "Фильтры", + "new": "Новый фильтр", + "search": "Поиск по пути…", + "refresh": "Обновить", + "retry": "Повторить", + "empty": "Нет подходящих фильтров.", + "loadError": "Не удалось загрузить фильтры.", + "toggleError": "Не удалось изменить состояние фильтра", + "system": "Системный", + "custom": "Пользовательский", + "systemReadonly": "Системные фильтры доступны только для чтения", + "view": "Просмотр", + "edit": "Изменить", + "ownership": { + "all": "Все", + "system": "Системные", + "custom": "Пользовательские" + }, + "state": { + "all": "Все", + "active": "Активные", + "inactive": "Неактивные" + }, + "col": { + "filter": "Фильтр", + "type": "Тип", + "active": "Активен", + "actions": "Действия" + }, + "pageInfo": "{{from}}–{{to}} из {{count}}" + }, + "editor": { + "createTitle": "Новый фильтр", + "editTitle": "Изменить фильтр", + "viewTitle": "Просмотр фильтра", + "relPath": "Путь", + "relPathHint": "Папка + файл, например syslog/my-filter.yaml", + "content": "Конвейер (YAML)", + "contentHint": "Шаги выполняются по порядку: grok, rename, delete, динамические плагины, …", + "save": "Сохранить", + "saving": "Сохранение…", + "saved": "Фильтр сохранён", + "saveError": "Не удалось сохранить фильтр", + "cancel": "Отмена", + "delete": "Удалить", + "deleteConfirm": "Удалить этот фильтр?", + "deleted": "Фильтр удалён", + "deleteError": "Не удалось удалить фильтр" + }, + "section": { + "overTime": "События во времени", + "top": "Топ", + "dropReasons": "Причины отбрасывания" + } }, - "manageLicense": "Управление лицензией", - "profile": { - "profile": "Профиль", - "license": "Лицензия", - "logout": "Выйти" - } - }, - "notifications": { - "title": "Уведомления", - "markAllRead": "Отметить все прочитанными", - "empty": "У вас нет уведомлений.", - "viewAll": "Показать все", - "markRead": "Отметить прочитанным", - "markUnread": "Отметить непрочитанным", - "delete": "Удалить", - "subtitle": "всего {{total}} · непрочитано {{unread}}", - "allCaughtUp": "Всё прочитано.", - "loadFailed": "Не удалось загрузить уведомления." - }, - "pagination": { - "perPage": "На странице", - "pageOf": "Страница {{page}} из {{total}}", - "previous": "Назад", - "next": "Вперёд" - }, - "license": { - "title": "Лицензия", - "subtitle": "Ваша редакция, возможности и файл лицензии.", - "loading": "Загрузка лицензии…", - "loadError": "Не удалось загрузить информацию о лицензии.", - "statusLabel": "Статус", - "status": { - "community": "Community", - "active": "Активна", - "expiring": "Скоро истекает", - "expired": "Истекла" + "incidents": { + "title": "Инциденты", + "subtitle": "Группируйте, сортируйте и закрывайте связанные оповещения как инциденты.", + "refresh": "Обновить", + "count_one": "{{count}} инцидент", + "count_few": "{{count}} инцидента", + "count_many": "{{count}} инцидентов", + "count_other": "{{count}} инцидента", + "openNow": "открыто сейчас", + "empty": "Нет подходящих инцидентов.", + "loadError": "Не удалось загрузить инциденты.", + "retry": "Повторить", + "unassigned": "Не назначен", + "unknownUser": "Неизвестно", + "status": { + "open": "Открыт", + "in_review": "На проверке", + "completed": "Завершён", + "merged": "Объединён" + }, + "sev": { + "high": "Высокая", + "medium": "Средняя", + "low": "Низкая", + "unknown": "Без оценки" + }, + "toolbar": { + "search": "Поиск инцидентов…", + "create": "Создать инцидент", + "allSeverities": "Все уровни серьёзности", + "export": "Экспорт в CSV" + }, + "statusTabs": { + "all": "Все" + }, + "filters": { + "add": "Добавить фильтр", + "clearAll": "Очистить всё", + "filterValues": "Фильтровать значения…", + "loadingValues": "Загрузка значений…", + "noValues": "Значения не найдены.", + "pickValue": "Выберите значение, чтобы добавить фильтр.", + "empty": "(пусто)", + "cancel": "Отмена", + "addBtn": "Добавить" + }, + "ops": { + "IS": "равно" + }, + "layout": { + "table": "Таблица", + "board": "Доска" + }, + "table": { + "name": "Инцидент", + "status": "Статус", + "severity": "Важность", + "assignee": "Ответственный", + "alerts": "Оповещения", + "created": "Создан" + }, + "drawer": { + "created": "Создан {{date}}", + "alertsCount": "{{count}} оповещений", + "solutionPlaceholder": "Решение / заметки по устранению…", + "solutionHint": "Сохраняется при переводе инцидента в «Завершён».", + "tabs": { + "overview": "Обзор", + "alerts": "Оповещения", + "notes": "Заметки", + "history": "История" + }, + "section": { + "description": "Описание", + "solution": "Решение", + "details": "Детали" + }, + "details": { + "id": "ID", + "status": "Статус", + "severity": "Важность", + "assignee": "Ответственный", + "created": "Создан", + "alerts": "Связанные оповещения" + } + }, + "alerts": { + "empty": "К этому инциденту не привязаны оповещения.", + "remove": "Отвязать оповещение", + "removeConfirm": "Отвязать «{{name}}» от этого инцидента?", + "removed": "Оповещение отвязано", + "removeError": "Не удалось отвязать оповещение", + "loadingAlert": "Загрузка оповещения…", + "alertGone": "Этого оповещения больше нет в хранилище — возможно, его удалило хранение.", + "alertFailed": "Не удалось загрузить оповещение.", + "openInAlerts": "Открыть в оповещениях" + }, + "notes": { + "empty": "Заметок пока нет.", + "add": "Добавить заметку", + "addError": "Не удалось добавить заметку", + "placeholder": "Напишите заметку…" + }, + "history": { + "empty": "Истории пока нет." + }, + "toast": { + "statusChanged": "Статус инцидента обновлён", + "statusError": "Не удалось изменить статус", + "exportFailed": "Не удалось экспортировать CSV" + }, + "assign": { + "assign": "Назначить", + "search": "Поиск пользователей…", + "unassign": "Снять назначение", + "noUsers": "Нет пользователей", + "assigned": "Назначено {{user}}", + "unassigned": "Назначение снято", + "error": "Не удалось изменить ответственного", + "custom": "Назначить произвольно", + "customPlaceholder": "Введите логин…" + }, + "action": { + "INCIDENT_CREATED": "Инцидент создан", + "INCIDENT_ALERT_ADD": "Оповещения добавлены", + "INCIDENT_ALERT_STATUS_CHANGED": "Статус оповещений изменён", + "INCIDENT_STATUS_CHANGE": "Статус изменён", + "INCIDENT_NOTE_ADD": "Заметка добавлена", + "INCIDENT_NOTE_CHANGE": "Заметка изменена", + "INCIDENT_ASSIGNED": "Назначение изменено" + }, + "create": { + "title": "Создать инцидент", + "stepIndicator": "Шаг {{current}} из {{total}}", + "selectedCount": "Выбрано оповещений: {{count}}", + "submit": "Создать", + "success": "Инцидент создан", + "error": "Не удалось создать инцидент", + "details": { + "nameLabel": "Название", + "namePlaceholder": "Короткое описательное название", + "descriptionLabel": "Описание", + "descriptionPlaceholder": "Контекст, область, первичные заметки…" + } + } }, - "edition": "Редакция", - "enterprise": "Enterprise", - "community": "Community", - "editionLine": "Редакция {{edition}}", - "datasourceLimit": "Лимит источников данных", - "unlimited": "Без ограничений", - "mssp": "MSSP / мультиарендность", - "enabled": "Включено", - "licenseType": "Тип лицензии", - "instanceId": "ID экземпляра", - "enterpriseUnlocked": "Функции Enterprise разблокированы", - "validUntil": "Действует до", - "noExpiry": "Без срока действия", - "timeRemaining": "Осталось времени", - "expiredAgo": "Истекла {{days}} дн. назад", - "daysShort": "{{days}} дн.", - "msspShort": "MSSP", - "communityEdition": "Редакция Community", - "communityBlurb": "Бесплатная и с открытым исходным кодом. Загрузите лицензию Enterprise ниже, чтобы разблокировать мультиарендность, SSO, увеличенные лимиты источников данных и расширенное соответствие.", - "upgrade": "Перейти на Enterprise", - "uploadTitle": "Загрузить лицензию", - "uploadBlurb": "Установите или замените подписанный файл LICENSE. Сервер проверяет подпись и срок действия перед применением. Только для администраторов.", - "installLicense": "Установить лицензию", - "chooseFile": "Выбрать файл", - "noFileSelected": "Файл не выбран", - "toast": { - "installed": "Лицензия установлена — редакция {{edition}}.", - "adminRequired": "Для загрузки лицензии нужны права администратора.", - "invalid": "Недействительный или просроченный файл лицензии.", - "installFailed": "Не удалось установить лицензию." - }, - "ingestLimit": "Объём приёма", - "notMetered": "Без учёта", - "gbPerMonth": "{{gb}} ГБ/месяц" - }, - "audit": { - "title": "Журнал аудита", - "subtitle": "Запись всех действий, связанных с безопасностью.", - "totalEntries": "всего записей: {{total}}.", - "loadError": "Не удалось загрузить журнал аудита", - "stats": { - "totalEntries": "Всего записей", - "acrossAllTime": "За всё время", - "successRate": "Доля успешных", - "failuresOnPage_one": "{{count}} сбой на этой странице", - "failuresOnPage_few": "{{count}} сбоя на этой странице", - "failuresOnPage_many": "{{count}} сбоев на этой странице", - "failuresOnPage_other": "{{count}} сбоев на этой странице", - "topAction": "Частое действие", - "onPage": "{{count}} на этой странице", - "uniqueActors": "Уникальных пользователей", - "includingSystem": "Включая систему" - }, - "filters": { - "title": "Фильтры", - "clear": "Очистить", - "last24h": "За 24 ч", - "failuresOnly": "Только сбои", - "authEvents": "События входа", - "actionPrefix": "Префикс действия", - "actionPlaceholder": "напр. auth., user.update", - "status": "Статус", - "any": "Любой", - "resourceType": "Тип ресурса", - "resourceTypePlaceholder": "user, alert…", - "resourceId": "ID ресурса", - "user": "Пользователь", - "userPlaceholder": "логин…" - }, - "statusValue": { - "success": "Успех", - "failure": "Сбой" - }, - "table": { - "timestamp": "Время", - "actor": "Субъект", - "action": "Действие", - "resource": "Ресурс", - "status": "Статус", - "ip": "IP", - "loading": "Загрузка…", - "emptyTitle": "Нет записей аудита по этим фильтрам.", - "emptyHint": "Попробуйте очистить фильтры или расширить диапазон дат.", - "system": "система", - "view": "Открыть" - }, - "drawer": { - "entry": "запись №{{id}}", - "overview": "Обзор", - "raw": "Сырой JSON", - "error": "Ошибка", - "actor": "Субъект", - "resource": "Ресурс", - "ip": "IP", - "userAgent": "User agent", - "session": "Сеанс", - "metadata": "Метаданные", - "copy": "Копировать", - "copied": "Скопировано", - "copyJson": "Копировать JSON" - } - }, - "team": { - "title": "Команда", - "subtitle": "Управление пользователями и их ролями.", - "tabs": { - "members": "Участники", - "roles": "Роли и разрешения" - }, - "toast": { - "rolesLoadFailed": "Не удалось загрузить роли", - "userLoadFailed": "Не удалось загрузить пользователя", - "rolesUpdated": "Роли обновлены", - "userReactivated": "Пользователь повторно активирован", - "userDeactivated": "Пользователь деактивирован", - "tfaReset": "Двухфакторная аутентификация сброшена", - "invitationSent": "Приглашение отправлено", - "loginOrEmailInUse": "Этот логин или эл. почта уже используются", - "invalidRequest": "Неверный запрос", - "noPermission": "У вас нет прав для этого действия", - "userNotFound": "Пользователь не найден", - "operationFailed": "Операция не выполнена", - "emailInUse": "Эта почта уже используется", - "roleCreated": "Роль создана", - "roleUpdated": "Роль обновлена", - "roleDeleted": "Роль удалена", - "roleNameInUse": "Роль с таким идентификатором уже существует", - "roleImmutable": "Системные роли нельзя изменять", - "permissionsLoadFailed": "Не удалось загрузить разрешения", - "localUserCreated": "Локальный пользователь создан" - }, - "members": { - "searchPlaceholder": "Поиск по имени или почте…", - "invite": "Пригласить пользователя", - "colUser": "Пользователь", - "colRoles": "Роли", - "col2fa": "2FA", - "colStatus": "Статус", - "loading": "Загрузка пользователей…", - "loadFailed": "Не удалось загрузить пользователей.", - "retry": "Повторить", - "noSearchMatch": "Нет пользователей по вашему запросу.", - "none": "Пользователей пока нет.", - "noRole": "нет", - "on": "Вкл", - "off": "Выкл", - "countLabel_one": "{{count}} пользователь · страница {{page}} из {{pages}}", - "countLabel_few": "{{count}} пользователя · страница {{page}} из {{pages}}", - "countLabel_many": "{{count}} пользователей · страница {{page}} из {{pages}}", - "countLabel_other": "{{count}} пользователей · страница {{page}} из {{pages}}", - "federated": "SSO" - }, - "status": { - "inactive": "Неактивен", - "pendingPassword": "Ожидает пароль", - "active": "Активен", - "pending": "Приглашение отправлено", - "suspended": "Заблокирован" - }, - "drawer": { - "createdBy": "создан {{actor}}", - "loading": "Загрузка…", - "profileTitle": "Профиль", - "profileSubtitle": "Эти данные может изменить только сам пользователь — в своём профиле.", - "name": "Имя", - "username": "Имя пользователя", - "email": "Эл. почта", - "language": "Язык", - "accountTitle": "Учётная запись", - "status": "Статус", - "statusActive": "Активен", - "statusInactive": "Неактивен", - "tfa": "2FA", - "tfaEnabled": "Включена", - "tfaNotConfigured": "Не настроено", - "resetTfa": "Сбросить", - "resetTfaHint": "Отключить 2FA этого пользователя, чтобы он заново настроил её при следующем входе", - "resetTfaConfirmTitle": "Сбросить двухфакторную аутентификацию?", - "resetTfaConfirmBody": "Это отключит 2FA для {{name}}. Пользователь войдёт только по паролю и сможет снова настроить её в своём профиле.", - "resetTfaConfirm": "Сбросить 2FA", - "pendingPasswordNote": "Всё ещё использует временный пароль (приглашение не завершено).", - "lastModified": "Изменён {{time}}", - "rolesTitle": "Роли", - "rolesSubtitle": "Роли дают разрешения на модули. Пользователь может иметь несколько ролей.", - "noRoleWarning": "Роль не назначена — у пользователя не будет доступа к модулям.", - "deactivate": "Деактивировать", - "reactivate": "Активировать снова", - "waitingInvite": "Ожидание принятия приглашения пользователем.", - "cancel": "Отмена", - "saving": "Сохранение…", - "saveRoles": "Сохранить роли", - "created": "создан {{time}}", - "pendingNote": "Приглашение ещё не принято.", - "federatedNote": "Вход через поставщика удостоверений." - }, - "invite": { - "title": "Пригласить пользователя", - "description": "Учётная запись создаётся неактивной. Пользователь получит письмо, чтобы задать пароль и активировать её.", - "username": "Имя пользователя", - "usernameHint": "Не менее 3 символов.", - "email": "Эл. почта", - "firstName": "Имя", - "lastName": "Фамилия", - "roles": "Роли", - "cancel": "Отмена", - "sending": "Отправка…", - "send": "Отправить приглашение", - "name": "Имя", - "emailHint": "С этого адреса пользователь будет входить.", - "localDescription": "Учётная запись создаётся с паролем и немедленно активируется. Письмо не отправляется.", - "modeInvite": "Пригласить пользователя", - "modeLocal": "Создать локального пользователя", - "passwordLabel": "Пароль", - "passwordPlaceholder": "Задайте надёжный пароль", - "localUserNote": "Этот пользователь не получит письмо и будет автоматически активирован.", - "createLocal": "Создать пользователя", - "passwordRules": { - "length": "Не менее 8 символов", - "case": "Хотя бы одна заглавная и одна строчная буква", - "special": "Хотя бы один специальный символ" - }, - "emailInvalid": "Введите корректный адрес электронной почты" - }, - "rolePicker": { - "none": "Нет доступных ролей." - }, - "roles": { - "loading": "Загрузка ролей…", - "loadFailed": "Не удалось загрузить разрешения ролей.", - "readonlyNote": "Роли и их разрешения определяются системой и доступны только для чтения. Назначайте их пользователям на вкладке «Участники».", - "permissionsCount_one": "{{count}} разрешение", - "permissionsCount_few": "{{count}} разрешения", - "permissionsCount_many": "{{count}} разрешений", - "permissionsCount_other": "{{count}} разрешений", - "modulesCount_one": "{{count}} модуль", - "modulesCount_few": "{{count}} модуля", - "modulesCount_many": "{{count}} модулей", - "modulesCount_other": "{{count}} модулей", - "matrixTitle": "Матрица разрешений", - "matrixSubtitle": "Что может делать каждая роль, по модулям.", - "permission": "Разрешение", - "systemNote": "Системные роли поставляются с платформой и не редактируются. Созданные вами роли принадлежат этому арендатору.", - "newRole": "Новая роль", - "edit": "Изменить", - "delete": "Удалить", - "systemBadge": "Системная", - "createTitle": "Новая роль", - "editTitle": "Изменение роли", - "editorSubtitle": "Выберите, что разрешено этой роли. У пользователя может быть несколько ролей.", - "nameLabel": "Идентификатор", - "nameHint": "Используется в коде и API. Например, ROLE_AUDITOR.", - "displayNameLabel": "Отображаемое имя", - "descriptionLabel": "Описание", - "permissionsLabel": "Разрешения", - "selectedCount": "выбрано: {{count}}", - "toggleAll": "все", - "loadingPermissions": "Загрузка разрешений…", - "save": "Сохранить роль", - "deleteConfirmTitle": "Удалить эту роль?", - "deleteConfirmBody": "{{name}} будет удалена. Те, у кого есть только эта роль, потеряют доступ к модулям." - }, - "langDefault": "Системный по умолчанию", - "relative": { - "justNow": "только что", - "minutesAgo": "{{count}} мин. назад", - "hoursAgo": "{{count}} ч. назад", - "daysAgo": "{{count}} дн. назад" - }, - "roleNames": { - "ROLE_ADMIN": "Администратор", - "ROLE_USER": "Пользователь" - }, - "roleDescriptions": { - "ROLE_ADMIN": "Полный доступ ко всем ресурсам", - "ROLE_USER": "Стандартный пользователь с доступом на чтение на уровне модулей" - }, - "actions": { - "read": "Чтение", - "write": "Запись", - "delete": "Удаление" - }, - "resources": { - "adaudit": "Аудит AD", - "alerts": "Оповещения", - "audit": "Журнал аудита", - "compliance": "Соответствие", - "config": "Конфигурация", - "dashboards": "Панели", - "datasources": "Datasources", - "eventprocessing": "Обработка событий", - "idp": "Поставщики идентификации", - "incidents": "Инциденты", - "integrations": "Интеграции", - "loganalyzer": "Анализатор логов", - "opensearch": "OpenSearch", - "roles": "Роли", - "soar": "SOAR", - "users": "Пользователи", - "notifications": "Уведомления", - "socai": "SOC AI", - "tenant": "Арендаторы", - "threatintel": "Threat Intelligence" - } - }, - "apiKeys": { - "title": "API-ключи", - "subtitle": "Программные токены доступа к API UTMStack.", - "new": "Новый API-ключ", - "searchPlaceholder": "Поиск по имени или разрешённому IP…", - "refresh": "Обновить", - "loading": "Загрузка API-ключей…", - "loadFailed": "Не удалось загрузить API-ключи.", - "retry": "Повторить", - "noSearchMatch": "Нет API-ключей по вашему запросу.", - "empty": "API-ключей пока нет. Создайте первый.", - "anyIp": "Любой IP", - "never": "Никогда", - "count_one": "{{count}} ключ · страница {{page}} из {{pages}}", - "count_few": "{{count}} ключа · страница {{page}} из {{pages}}", - "count_many": "{{count}} ключей · страница {{page}} из {{pages}}", - "count_other": "{{count}} ключей · страница {{page}} из {{pages}}", - "enterprise": { - "title": "API-ключи — функция Enterprise", - "body": "Создавайте, ограничивайте и обновляйте API-ключи для программного доступа к API UTMStack. Эта возможность доступна в редакции Enterprise.", - "upgrade": "Перейти на Enterprise", - "manageLicense": "Управление лицензией" - }, - "col": { - "name": "Имя", - "allowedIps": "Разрешённые IP", - "created": "Создан", - "lastRotated": "Последняя ротация", - "expires": "Истекает", - "status": "Статус", - "actions": "Действия" - }, - "status": { - "active": "Активен", - "expiring": "Истекает", - "expired": "Истёк" - }, - "action": { - "rotate": "Ротация", - "edit": "Изменить", - "delete": "Удалить" - }, - "dialog": { - "editTitle": "Изменить API-ключ", - "newTitle": "Новый API-ключ", - "name": "Имя", - "namePlaceholder": "ci-pipeline", - "allowedIps": "Разрешённые IP", - "allowedIpsHint": "Через запятую. Оставьте пустым, чтобы разрешить любой IP.", - "expires": "Истекает", - "expiresHint": "Оставьте пустым, чтобы ключ не истекал.", - "secretNote": "Секретный токен показывается один раз, сразу после создания. Скопируйте его — позже его нельзя получить (только ротация).", - "cancel": "Отмена", - "saving": "Сохранение…", - "saveChanges": "Сохранить изменения", - "createKey": "Создать ключ" - }, - "confirm": { - "deleteTitle": "Удалить API-ключ", - "rotateTitle": "Ротация API-ключа", - "deleteBody": "Удалить {{name}}? Любой клиент, использующий его, немедленно потеряет доступ. Действие необратимо.", - "rotateBody": "Выполнить ротацию {{name}}? Будет выдан новый секрет, а текущий немедленно перестанет работать. Новый токен показывается один раз.", - "cancel": "Отмена", - "working": "Выполнение…", - "delete": "Удалить", - "rotate": "Ротация" - }, - "reveal": { - "title": "API-ключ создан", - "note": "Скопируйте этот секрет сейчас — для {{name}}. Он больше не будет показан. Если потеряете — выполните ротацию ключа.", - "copied": "Скопировано", - "copy": "Копировать", - "done": "Готово" - }, - "toast": { - "updated": "API-ключ обновлён", - "secretIssueFailed": "Ключ создан, но секрет не удалось выдать. Используйте «Ротация», чтобы получить его.", - "deleted": "API-ключ удалён" - }, - "error": { - "nameTaken": "API-ключ с таким именем уже существует", - "enterpriseRequired": "API-ключи требуют редакцию Enterprise", - "notFound": "API-ключ не найден", - "invalidRequest": "Неверный запрос", - "failed": "Операция не выполнена" - } - }, - "idp": { - "title": "Поставщики удостоверений", - "subtitle": "Единый вход SAML 2.0 для вашей организации.", - "add": "Добавить поставщика", - "enterprise": { - "title": "SSO — функция Enterprise", - "body": "Подключите поставщика удостоверений SAML 2.0 (Entra ID, Okta, Google Workspace…), чтобы команда входила через ваш IdP. Единый вход доступен в редакции Enterprise.", - "upgrade": "Перейти на Enterprise" - }, - "loading": "Загрузка поставщиков удостоверений…", - "loadFailed": "Не удалось загрузить поставщиков удостоверений.", - "retry": "Повторить", - "empty": { - "title": "Поставщики удостоверений не настроены", - "body": "Добавьте поставщика SAML 2.0, чтобы команда входила через корпоративный IdP." - }, - "card": { - "enable": "Включить", - "disable": "Отключить", - "active": "Активен", - "disabled": "Отключён", - "metadataUrl": "URL метаданных", - "spEntityId": "SP Entity ID", - "spAcsUrl": "SP ACS URL", - "loginUrl": "URL входа", - "copy": "Копировать", - "edit": "Изменить", - "delete": "Удалить", - "jit": "Provisioning", - "jitOn": "creates accounts on first sign-in", - "sync": "Roles", - "syncOn": "re-applied on every sign-in" - }, - "form": { - "addTitle": "Добавить поставщика удостоверений", - "editTitle": "Изменить поставщика удостоверений", - "name": "Имя", - "nameHint": "Уникальное. Используется в URL SSO.", - "providerType": "Тип поставщика", - "providerTypeHint": "Метка, напр. azure, okta, google.", - "metadataUrl": "URL метаданных IdP", - "spEntityId": "SP Entity ID", - "spAcsUrl": "SP ACS URL", - "certificate": "Сертификат SP (PEM)", - "privateKey": "Приватный ключ SP (PEM)", - "privateKeyHintEdit": "Оставьте пустым, чтобы сохранить текущий ключ.", - "privateKeyHintCreate": "Обязательно. Хранится в зашифрованном виде; больше не показывается.", - "privateKeyUnchanged": "•••••••• (без изменений)", - "active": "Активен (показывать на странице входа)", - "cancel": "Отмена", - "saving": "Сохранение…", - "save": "Сохранить изменения", - "create": "Создать поставщика", - "issuer": "Issuer URL", - "issuerHint": "Discovery runs against this; the provider must serve /.well-known/openid-configuration under it.", - "clientId": "Client ID", - "redirectUrl": "Redirect URL", - "redirectUrlHint": "Register this exact URL with the provider.", - "host": "Host", - "port": "Port", - "startTls": "TLS", - "startTlsOn": "Use StartTLS", - "bindDn": "Bind DN", - "bindDnHint": "A service account that may search the directory.", - "baseDn": "Base DN", - "userFilter": "User filter", - "userFilterHint": "Must contain %s, where the address typed at login is placed.", - "emailAttribute": "Email attribute", - "nameAttribute": "Name attribute", - "groupAttribute": "Group attribute", - "provisioning": "Accounts and roles", - "provisioningHint": "What happens when someone the directory vouches for signs in.", - "jit": "Create the account on first sign-in", - "defaultRole": "Default role", - "defaultRoleHint": "Given when no group matches. Without one, an unmatched sign-in is refused.", - "noDefaultRole": "None", - "groupsAttribute": "Groups attribute", - "groupsAttributeHint": "Where the provider puts group membership.", - "syncRoles": "Re-apply roles on every sign-in", - "syncRolesHint": "Roles not in the mapping are removed, so a change in the directory reaches here. Without this, a demotion never arrives.", - "mappings": "Group to role", - "mappingsHint": "A directory group on the left, the role it grants on the right.", - "addMapping": "Add", - "noMappings": "No mappings. Everyone gets the default role.", - "groupPlaceholder": "SOC Analysts", - "pickRole": "Pick a role", - "secret.saml": "SP private key", - "secret.oidc": "Client secret", - "secret.ldap": "Bind password", - "secretHintCreate": "Stored encrypted and never shown again.", - "secretHintEdit": "Leave blank to keep the stored one.", - "secretUnchanged": "без изменений", - "errors": { - "required": "Это поле обязательно.", - "url": "Должно быть корректным URL http(s).", - "httpsUrl": "Должно быть корректным URL https.", - "hostname": "Введите хост или IP без схемы (например, ldap.example.com).", - "port": "Порт должен быть целым числом от 0 до 65535.", - "pemCertificate": "Не похоже на сертификат PEM (нет -----BEGIN/END CERTIFICATE-----).", - "pemKey": "Не похоже на закрытый ключ PEM (нет -----BEGIN/END PRIVATE KEY-----).", - "userFilterPlaceholder": "Фильтр должен содержать %s, куда подставляется адрес входа.", - "userFilterUnbalanced": "Круглые скобки не сбалансированы — поиск ничего не вернёт.", - "nameFormat": "Используйте буквы, цифры, точки, дефисы или подчёркивания (макс. 64). Это имя входит в URL SSO, пробелы недопустимы.", - "redirectUrl": "Должно быть корректным URL https либо http-loopback URL (localhost / 127.0.0.1 / [::1]).", - "entityId": "Должно быть корректным URI, например, https://utmstack.example.com/sp." - } - }, - "delete": { - "title": "Удалить поставщика удостоверений", - "body": "Удалить {{name}}? Пользователи больше не смогут входить через него. Действие необратимо.", - "cancel": "Отмена", - "deleting": "Удаление…", - "confirm": "Удалить" - }, - "toast": { - "enabled": "Поставщик включён", - "disabled": "Поставщик отключён", - "created": "Поставщик удостоверений создан", - "updated": "Поставщик удостоверений обновлён", - "deleted": "Поставщик удостоверений удалён", - "paidPlan": "SAML SSO требует платный план", - "enterpriseRequired": "SSO требует редакцию Enterprise", - "notFound": "Поставщик удостоверений не найден", - "invalid": "Неверная конфигурация", - "failed": "Операция не выполнена" - }, - "providerType": { - "saml": "SAML 2.0", - "oidc": "OpenID Connect", - "ldap": "LDAP / Active Directory", - "comingSoon": "пока недоступно" - } - }, - "userAuditor": { - "title": "Аудит пользователей", - "subtitle": "Учётные записи Active Directory, замеченные в журналах безопасности Windows — обнаружены из событий создания, входа и удаления.", - "export": "Экспорт", - "accountsChip": "{{count}} учётных записей", - "overview": { - "title": "Инвентарь учётных записей", - "active": "активные", - "disabled": "отключённые", - "deleted": "удалённые", - "seen24h": "{{count}} замечено за последние 24 часа", - "byDomain": "По домену" - }, - "views": { - "all": "Все учётные записи", - "windows": "Windows", - "linux": "Linux", - "active": "Активные", - "disabled": "Отключённые", - "deleted": "Удалённые", - "service": "Служебные учётные записи", - "stale": "Устаревшие (30+ дн.)" - }, - "searchPlaceholder": "Поиск по имени учётной записи или SID…", - "allTenants": "Все арендаторы", - "filters": { - "add": "Добавить фильтр", - "clearAll": "Очистить всё", - "filterValues": "Фильтровать значения…", - "loadingValues": "Загрузка значений…", - "noValues": "Значения не найдены.", - "pickValue": "Выберите значение, чтобы добавить фильтр.", - "empty": "(пусто)", - "cancel": "Отмена", - "addBtn": "Добавить" - }, - "filterFields": { - "status": "Статус жизненного цикла" - }, - "ops": { - "is": "равно" - }, - "refresh": "Обновить", - "layout": { - "list": "Список", - "cards": "Карточки" - }, - "list": { - "account": "Учётная запись", - "identity": "Идентификатор", - "sid": "SID", - "status": "Статус", - "lastLogon": "Последний вход", - "lastSeen": "Последняя активность", - "tenant": "Арендатор" - }, - "status": { - "active": "Активна", - "disabled": "Отключена", - "deleted": "Удалена" - }, - "badge": { - "service": "служебная", - "stale": "устаревшая" - }, - "empty": "Нет учётных записей для этого представления.", - "loadError": "Не удалось загрузить учётные записи AD.", - "retry": "Повторить", - "card": { - "lastLogon": "Последний вход" - }, - "pageInfo": "{{from}}–{{to}} из {{count}}", - "drawer": { - "tenantInline": "арендатор {{id}}", - "serviceAccount": "служебная учётная запись", - "stale": "устарела 30+ дн.", - "viewInLogs": "Открыть события в обозревателе логов", - "copySid": "Копировать SID", - "copyUid": "Копировать идентификатор", - "copied": "Скопировано", - "identity": "Идентификация", - "accountName": "Имя учётной записи", - "domain": "Домен", - "hostname": "Имя хоста", - "sid": "SID", - "uidNumber": "UID", - "machineId": "ID машины", - "tenant": "Арендатор", - "adStatus": "Статус AD", - "enabled": "Включена", - "disabled": "Отключена", - "lifecycle": "Жизненный цикл", - "created": "Учётная запись создана", - "lastLogon": "Последний вход", - "lastSeen": "Последняя активность в логах", - "deleted": "Учётная запись удалена", - "noLifecycle": "Нет записей о событиях жизненного цикла." - }, - "relative": { - "justNow": "только что", - "minutesAgo": "{{count}} мин. назад", - "hoursAgo": "{{count}} ч. назад", - "daysAgo": "{{count}} дн. назад" - }, - "none": "—" - }, - "connectionKey": { - "title": "Ключ подключения", - "subtitle1": "Ключ, который агенты предъявляют при регистрации на этом экземпляре.", - "subtitleEmphasis": "Используется только для установки агентов", - "subtitle2": "— не для коллекторов, интеграций или API. Управляется agent-manager.", - "status": { - "label": "Статус", - "loading": "Загрузка…", - "unavailable": "Agent-manager недоступен", - "active": "Активен", - "unavailableHint": "Не удалось связаться с agent-manager для чтения ключа.", - "activeHint": "Агенты могут регистрироваться по этому ключу." - }, - "token": { - "title": "Ключ подключения", - "subtitle": "Относитесь к этому значению как к учётным данным. Ротация выдаёт новый ключ для будущих установок агентов — уже зарегистрированные агенты продолжают работать.", - "loadFailedTitle": "Не удалось загрузить ключ подключения", - "unavailableTitle": "Ключ подключения недоступен", - "loadFailedHint": "Ключом управляет agent-manager, который не ответил. Повторите попытку через мгновение.", - "retry": "Повторить", - "show": "Показать ключ", - "hide": "Скрыть ключ", - "copy": "Копировать", - "copied": "Скопировано", - "regenerate": "Перегенерировать ключ подключения", - "confirmTitle": "Перегенерировать ключ?", - "confirmBody": "Новым установкам агентов потребуется новый ключ. Уже зарегистрированные агенты продолжат работать. Отменить нельзя.", - "regenerating": "Перегенерация…", - "confirmYes": "Да, перегенерировать", - "cancel": "Отмена" - }, - "security": { - "title": "Рекомендации по безопасности", - "subtitle": "Лучшие практики защиты этих учётных данных.", - "rotateTitle": "Ротация каждые 90 дней", - "rotateBody": "Запланируйте регулярную ротацию. UTMStack может отправить вам напоминание по эл. почте, когда ключу больше 90 дней.", - "rotateAction": "Настроить напоминание", - "secretTitle": "Храните как секрет", - "secretBody": "Не добавляйте в систему контроля версий. Используйте менеджер секретов (Vault, AWS SM и т. п.) и подставляйте при установке.", - "auditTitle": "Аудит, кто его получил", - "auditBody": "Каждое получение и ротация фиксируются в журнале аудита приложения.", - "auditAction": "Открыть журнал аудита" - }, - "toast": { - "loadFailed": "Не удалось загрузить ключ подключения", - "rotated": "Ключ подключения ротирован", - "rotateFailed": "Не удалось ротировать ключ подключения", - "copyFailed": "Не удалось скопировать" - } - }, - "dataRetention": { - "title": "Хранение данных", - "subtitle": "How long each dataset is kept, and when its records stop costing local disk.", - "loading": "Загрузка…", - "loadFailed": "Could not read the store.", - "retry": "Повторить", - "datasets": { - "logs": "Logs", - "alerts": "Alerts", - "statistics": "Ingestion statistics" - }, - "holding": "{{documents}} records · {{size}}", - "since": "since {{date}}", - "diskUsed": "Disk {{pct}}% used", - "keep": "Delete after", - "keepHint": "A record is deleted this many days after it happened, wherever it is stored by then.", - "cold": "Move to cold storage after", - "coldHint": "Older records move to object storage and stay queryable. 0 keeps everything on local disk.", - "coldUnavailable": "Set up cold storage below to move older records off local disk.", - "coldBeforeDelete": "Records have to move before they are deleted: use fewer days than the lifetime, or 0.", - "tieredNote": "This dataset moves records to cold storage. Going back to local-only needs the table rebuilt, so it cannot be turned off here.", - "days": "дней", - "save": "Сохранить", - "saving": "Сохранение…", - "toast": { - "saved": "Retention saved", - "noPermission": "You do not have permission to change retention", - "saveFailed": "Could not save the retention" - }, - "coldStorage": { - "title": "Cold storage", - "hint": "An object store the event store treats as a second, slower disk. Older records move there and are still queried from the same place — it is not an archive and nothing has to be restored.", - "active": "In use", - "inactive": "Not set up", - "writtenNotReady": "The bucket is configured but the store has not picked it up. Check that the deployment shares the store's configuration directory.", - "endpoint": "Bucket URL", - "accessKey": "Access key", - "secretKey": "Secret key", - "bucketLocked": "The credentials can be changed at any time. The bucket cannot, once records live in it: the parts already moved carry it.", - "enable": "Enable cold storage", - "update": "Update credentials", - "toast": { - "saved": "Cold storage configured", - "failed": "Could not configure cold storage" - }, - "kind": "Тип", - "kind_s3": "Объектное хранилище, совместимое с S3", - "kind_local": "Локальная папка или NFS", - "kind_azure": "Azure Blob Storage", - "accountUrl": "URL учётной записи хранилища", - "container": "Контейнер", - "accountName": "Имя учётной записи", - "accountKey": "Ключ учётной записи", - "useRole": "Использовать IAM-роль сервера вместо ключей", - "s3Hint": "Работает с AWS S3 и любым S3-совместимым хранилищем: MinIO, Ceph, Wasabi, Cloudflare R2 или Google Cloud Storage (endpoint https://storage.googleapis.com// с HMAC-ключами).", - "localHint": "Записи переносятся в папку, смонтированную как /mnt/utmstack-cold внутри хранилища событий: обычный каталог в папке данных или NFS-ресурс, смонтированный на хосте поверх <каталог данных>/clickhouse/cold до запуска стека. Учётные данные не нужны.", - "changeWarning": "Records already moved to the current destination are not migrated. They stay there and stop being readable from here until the old destination is copied across by hand." - }, - "forbidden": { - "title": "Эта страница принадлежит платформе", - "body": "Хранение относится к таблицам, общим для всех тенантов: читать и менять его может только администратор платформы." - } - }, - "about": { - "title": "Об этом экземпляре", - "subtitle": "Версия, лицензия и состояние системы этого развёртывания UTMStack.", - "loading": "Загрузка информации об экземпляре…", - "edition": { - "enterprise": "Enterprise", - "community": "Community" - }, - "fields": { - "hostname": "Сервер", - "instanceId": "ID экземпляра", - "noInstanceMeta": "Метаданные экземпляра недоступны." - }, - "license": { - "title": "Лицензия", - "enterpriseMssp": "Enterprise · MSSP", - "datasources": "Datasources", - "communityLimited": "Лимит Community", - "unlimited": "Без ограничений", - "expires": "Истекает", - "managedNote": "Редакция, лимиты datasources и загрузка лицензии управляются на странице «Лицензия».", - "view": "Открыть лицензию", - "ingest": "Объём приёма", - "notMetered": "Без учёта", - "gbPerMonth": "{{gb}} ГБ/месяц" - }, - "services": { - "backend": { - "name": "Backend API", - "desc": "REST-шлюз, аутентификация и оркестрация модулей." - }, - "opensearch": { - "name": "OpenSearch", - "desc": "Хранилище логов и событий.", - "detail": "{{nodes}} узлов · {{shards}} шардов" - }, - "unreachable": "Недоступно" - }, - "status": { - "up": "В норме", - "degraded": "Снижено", - "down": "Недоступно", - "unknown": "Неизвестно" - }, - "health": { - "title": "Состояние системы", - "allHealthy": "Все сервисы в норме. Обновите для повторной проверки.", - "issues_one": "{{count}} сервис требует внимания.", - "issues_few": "{{count}} сервиса требуют внимания.", - "issues_many": "{{count}} сервисов требуют внимания.", - "issues_other": "{{count}} сервисов требуют внимания.", - "refresh": "Обновить" - }, - "usage": { - "title": "Источники данных", - "subtitle": "Источники данных, настроенные в этой установке.", - "ofUnlimited": "из неограниченного", - "ofLimit": "из {{limit}}", - "overLimit": "Превышен лицензионный лимит — данные сверх лимита под угрозой.", - "configured": "настроено" - }, - "support": { - "title": "Поддержка", - "docs": "Документация", - "repo": "Репозиторий GitHub", - "issues": "Сообщить о проблеме", - "website": "utmstack.com" - }, - "legal": { - "title": "Юридическая информация", - "license": "Лицензия", - "security": "Сообщение об уязвимости", - "copyright": "© {{year}} UTMStack. Все права защищены." - } - }, - "logExplorer": { - "title": "Просмотр логов", - "eventsIn": "событий в", - "searching": "Поиск…", - "query": { - "allDataTypes": "Все типы данных", - "dataTypes": "Типы данных", - "exportCsv": "Экспорт CSV", - "filterDataTypes": "Фильтр типов данных…", - "noDataTypes": "Нет типов данных", - "noDataTypesMatch": "Нет подходящих типов данных", - "noTextSearch": "У этого источника нет полнотекстового поля — фильтруйте по полю", - "refresh": "Обновить", - "run": "Выполнить", - "search": "Искать", - "searchPlaceholder": "Поиск по всем полям…" - }, - "time": { - "15m": "Последние 15 минут", - "1h": "Последний час", - "6h": "Последние 6 часов", - "24h": "Последние 24 часа", - "7d": "Последние 7 дней", - "30d": "Последние 30 дней" - }, - "ops": { - "is": "равно", - "isNot": "не равно", - "contains": "содержит", - "exists": "существует", - "between": "между", - "search": "поиск", - "isOneOf": "один из", - "isNotOneOf": "no es ninguno de", - "doesNotContain": "no contiene", - "startsWith": "empieza con", - "doesNotStartWith": "no empieza con", - "endsWith": "termina con", - "doesNotEndWith": "no termina con", - "doesNotExist": "no existe", - "notBetween": "no está entre", - "greaterThan": "es mayor que", - "greaterThanOrEquals": "es mayor o igual que", - "lessThan": "es menor que", - "lessThanOrEquals": "es menor o igual que" - }, - "filters": { - "label": "Фильтры", - "clearAll": "Очистить всё" - }, - "fields": { - "title": "Поля", - "filterPlaceholder": "Фильтр полей…", - "none": "Нет полей", - "selected": "Выбранные поля", - "available": "Доступные поля", - "topValues_one": "Топ {{count}} значение", - "topValues_few": "Топ {{count}} значения", - "topValues_many": "Топ {{count}} значений", - "topValues_other": "Топ {{count}} значений", - "loading": "Загрузка…", - "noValues": "Нет значений", - "addColumn": "Добавить как столбец", - "removeColumn": "Убрать столбец из таблицы", - "filterFor": "Фильтровать по значению", - "filterOut": "Исключить значение", - "empty": "(пусто)" - }, - "results": { - "dataTypesFailed": "Не удалось загрузить типы данных.", - "endOfResults": "Загружено событий: {{count}}", - "loadingMore": "Загрузка ещё…", - "message": "Сообщение", - "none": "Нет логов по этому запросу.", - "removeColumn": "Убрать {{field}}", - "retry": "Повторить", - "searchFailed": "Поиск не удался.", - "searching": "Поиск…", - "source": "Источник", - "time": "Время", - "scope": "Поиск выполнен в {{dataset}} · {{dataType}}.", - "searchAllDataTypes": "Искать по всем типам" - }, - "detail": { - "fieldsCount_one": "{{count}} поле", - "fieldsCount_few": "{{count}} поля", - "fieldsCount_many": "{{count}} полей", - "fieldsCount_other": "{{count}} полей", - "copyJson": "Копировать JSON", - "copied": "Документ скопирован", - "parsedFields": "Разобранные поля", - "json": "JSON", - "filterFor": "Фильтровать по", - "filterOut": "Исключить", - "surrounding": "Окружающие события", - "surroundingHint": "Показать события ±15 мин вокруг этого, из того же источника" - }, - "view": { - "table": "Таблица", - "chart": "График" - }, - "chart": { - "aggregateOn": "Агрегировать по", - "per": "по", - "topValues": "— топ 20 значений", - "building": "Построение графика…", - "failed": "Не удалось построить график для этого поля.", - "noData": "Нет данных для графика." - }, - "intervals": { - "minute": "Минута", - "hour": "Час", - "day": "День", - "week": "Неделя", - "month": "Месяц", - "quarter": "Квартал", - "year": "Год" - }, - "toast": { - "exportFailed": "Экспорт не удался" - }, - "builder": { - "add": "Добавить фильтр", - "filterValues": "Фильтр значений…", - "loadingValues": "Загрузка значений…", - "noValues": "Значения не найдены.", - "cancel": "Отмена", - "confirm": "Добавить", - "pickValue": "Pick a value to add the filter." - }, - "related": { - "nLogs_one": "{{count}} лог", - "nLogs_other": "{{count}} логов", - "truncated": "Показаны первые {{count}} связанных логов (полный набор больше)." - }, - "saved": { - "title": "Сохранённые", - "empty": "Сохранённых запросов пока нет", - "saveCurrent": "Сохранить текущий запрос", - "save": "Сохранить", - "namePlaceholder": "Название запроса", - "delete": "Удалить", - "saved": "Сохранено «{{name}}»", - "loading": "Загрузка…", - "loadFailed": "Не удалось загрузить сохранённые запросы", - "saveFailed": "Не удалось сохранить запрос", - "deleteFailed": "Не удалось удалить запрос", - "unreadable": "Не удалось прочитать этот сохранённый запрос" - } - }, - "integrations": { - "title": "Интеграции", - "searchPlaceholder": "Поиск интеграций…", - "noMatch": "Нет совпадающих интеграций.", - "browseMarketplace": "Обзор marketplace", - "loading": "Загрузка интеграций…", - "addCustom": { - "title": "Добавить пользовательскую интеграцию", - "description": "Создать новый пользовательский источник", - "cta": "Создать" - }, - "tabs": { - "all": "Все", - "agents": "Агенты", - "collectors": "Коллекторы", - "cloud": "Cloud", - "custom": "Пользовательская" - }, - "kind": { - "agents & syslog": "Агент", - "device": "Коллектор", - "antivirus": "Коллектор", - "other": "Коллектор", - "custom": "Пользовательская", - "cloud": "Cloud", - "utmstack modules": "Коллектор" - }, - "status": { - "configured": "Настроена", - "available": "Доступна" - }, - "card": { - "manage": "Управлять →", - "setup": "Настроить →", - "eventsPerSec": "{{rate}} с/с", - "enabled": "Включено", - "setupShort": "Настроить" - }, - "drawer": { - "manage": "Управлять", - "viewEvents": "Просмотр событий", - "documentation": "Документация", - "getInstallCmd": "Получить команду установки", - "setupCollector": "Настроить коллектор", - "connect": "Подключить", - "configureCustom": "Настроить пользовательский источник", - "eventsRate": "{{rate}} событий/с · {{count}} за 24ч", - "manageRules": "Правила", - "manageFilters": "Фильтры", - "openDashboard": "Abrir panel" - }, - "setup": { - "agent": { - "howItWorksTitle": "Как это работает", - "howItWorksBody": "Агент {{name}} — это небольшой демон, работающий на хосте и пересылающий локальные события в UTMStack по аутентифицированному TLS-соединению. Он обновляется автоматически и сообщает о своем состоянии здоровья.", - "installTitle": "Установить на {{name}}", - "installHint": "Выполните эту команду на каждом хосте {{name}}, который вы хотите отслеживать. Токен уже кодирует ваше текущее рабочее пространство.", - "afterTitle": "Что вы увидите после установки", - "after1": "Хост появляется в разделе Источники данных примерно через 60 секунд после запуска агента.", - "after2": "Телеметрия начинает поступать в Log Explorer, ограничиваясь вашим рабочим пространством.", - "after3": "Агент автоматически сообщает состояние CPU/памяти/диска обратно в UTMStack.", - "actionLabel": "Действие", - "platformLabel": "Платформа", - "optionsLabel": "Опции", - "skipCertValidation": "Не проверять TLS-сертификат (самоподписанный сервер)", - "noRemoteControl": "Отключить удалённое выполнение команд на этом хосте", - "loadingToken": "Загрузка токена…", - "actions": { - "install": "Установить", - "uninstall": "Удалить" - }, - "prereqTitle": "Требования перед установкой", - "prereqBody": "Агент UTMStack взаимодействует с сервером через следующие порты. Убедитесь, что они открыты между хостом и UTMStack перед установкой:", - "sensitiveWarning": "Команда ниже содержит конфиденциальный токен регистрации — не передавайте его третьим лицам.", - "uninstall": { - "title": "Удалить агент", - "body": "Выполните это на хосте, чтобы остановить и удалить агент UTMStack и его службы. Используется платформа, выбранная выше." - }, - "macCompat": "Требуется macOS 11 (Big Sur) или новее на Apple Silicon (M1/M2/M3 или новее). Mac на базе Intel не поддерживаются." - }, - "collector": { - "howItWorksTitle": "Как это работает", - "howItWorksBody": "{{name}} не запускает агент UTMStack. Вместо этого вы устанавливаете коллектор UTMStack где-нибудь в сети, которая доступна как вашему устройству {{name}}, так и UTMStack. {{name}} отправляет syslog на коллектор, коллектор анализирует, нормализует и пересылает события в UTMStack.", - "step1Title": "1 · Установить коллектор UTMStack", - "step1Hint": "Запустите на хосте Linux с сетевым доступом с устройства {{name}}.", - "step2Title": "2 · Настроить {{name}} для отправки syslog", - "step2Hint": "На устройстве {{name}} направьте пересылку syslog на адрес коллектора на {{port}}.", - "vendorDocs": "Смотрите инструкции для конкретного поставщика", - "step3Title": "3 · Проверка", - "step3Body": "Через несколько минут вы должны увидеть события {{name}} в source: {{source}} в Log Explorer и новую запись в Источниках данных.", - "endpoint": { - "title": "Параметры подключения", - "hint": "Настройте {{name}} для пересылки журналов на Collector, используя хост и порт ниже." - }, - "syslog": { - "sections": { - "sendLogs": { - "title": "1 · Отправка журналов в UTMStack", - "body": "Настройте устройство для отправки syslog-сообщений по UDP (514) или TCP (514) на агент UTMStack." - }, - "enableCollector": { - "title": "2 · Включение syslog-коллектора", - "body": "Включите коллектор журналов и syslog-интеграцию в файле конфигурации там, где установлен агент UTMStack." - }, - "activate": { - "title": "3 · Активация", - "body": "Активируйте модуль UTMStack, чтобы события начали поступать в Log Explorer." - } - } - }, - "netflow": { - "source": "Сетевое устройство", - "step1": { - "title": "Включить слушатель NetFlow на Collector", - "body": "На хосте, где установлен Collector, выполните эту команду, чтобы открыть коллектор NetFlow на порту 2055:", - "note": "NetFlow использует только UDP — TCP и TLS не поддерживаются для этого протокола." - }, - "step2": { - "title": "Настройте устройство для экспорта NetFlow", - "body": "Направьте экспорт NetFlow с вашего маршрутизатора или межсетевого экрана на Collector-хост, порт {{port}} UDP. Пример ниже предназначен для Cisco IOS — для других платформ обратитесь к документации производителя:", - "note": "Замените на имя интерфейса, на котором должен отслеживаться трафик (например, GigabitEthernet0/0). Примените ingress/egress для каждого нужного интерфейса." - } - }, - "cisco": { - "source": "Cisco ASA", - "step1": { - "title": "Включить слушатель Cisco ASA на Collector", - "body": "На хосте, где установлен Collector, выполните эту команду, чтобы открыть слушатель журналов Cisco ASA:", - "note": "Чтобы использовать TCP вместо UDP, замените udp на tcp в приведённой выше команде." - }, - "step2": { - "title": "Настроить Cisco ASA для пересылки журналов", - "body": "На вашем Cisco ASA включите syslog и направьте его на Collector-хост, порт {{port}}. Выполните эти команды в привилегированном режиме EXEC (замените на имя внутреннего или управляющего интерфейса):" - } - }, - "ciscoSwitch": { - "source": "Cisco Switch", - "step1": { - "title": "Включить слушатель Cisco Switch на Collector", - "body": "На хосте, где установлен Collector, выполните эту команду, чтобы открыть слушатель журналов Cisco Switch:", - "note": "Чтобы использовать TCP вместо UDP, замените udp на tcp в приведённой выше команде." - }, - "step2": { - "title": "Настроить коммутатор для пересылки журналов", - "body": "В привилегированном режиме EXEC на вашем коммутаторе Cisco включите syslog и направьте его на Collector-хост, порт {{port}}:" - } - }, - "ciscoMeraki": { - "source": "Cisco Meraki", - "step1": { - "title": "Включить слушатель Cisco Meraki на Collector", - "body": "На хосте, где установлен Collector, выполните эту команду, чтобы открыть слушатель журналов Cisco Meraki:", - "note": "Чтобы использовать TCP вместо UDP, замените udp на tcp в приведённой выше команде." - }, - "step2": { - "title": "Настроить Meraki для пересылки журналов", - "body": "В Meraki Dashboard перейдите в Network-wide → Configure → General, прокрутите до раздела Reporting и добавьте syslog-сервер с IP Collector и портом {{port}}. Выберите все роли, которые нужно пересылать." - } - }, - "ciscoFirepower": { - "source": "Cisco Firepower", - "step1": { - "title": "Включить слушатель Cisco Firepower на Collector", - "body": "На хосте, где установлен Collector, выполните эту команду, чтобы открыть слушатель журналов Cisco Firepower:", - "note": "Чтобы использовать TCP вместо UDP, замените udp на tcp в приведённой выше команде." - }, - "step2": { - "title": "Настроить Firepower для пересылки журналов", - "body": "В Firepower Management Center (FMC) перейдите в Devices → Platform Settings, отредактируйте или создайте политику и перейдите в Syslog → Syslog Servers. Добавьте IP Collector с портом {{port}} (UDP), затем назначьте политику вашим устройствам и выполните развёртывание." - } - }, - "vmware": { - "source": "VMware ESXi", - "step1": { - "title": "Включить слушатель VMware на Collector", - "body": "На хосте, где установлен Collector, выполните эту команду, чтобы открыть syslog-слушатель VMware ESXi. ESXi передаёт данные по TCP:", - "note": "Для зашифрованного канала используйте tls вместо tcp (предварительно загрузите сертификаты на Collector)." - }, - "step2": { - "title": "Направить syslog ESXi на Collector", - "body": "Откройте сессию SSH/ESXi Shell на хосте (или используйте vSphere Client: Host → Configure → Advanced System Settings → Syslog.global.logHost). Задайте удалённый loghost как {{host}}:{{port}} и перезагрузите конфигурацию:", - "note": "В vSphere можно вместо этого задать Syslog.global.logHost с тем же значением tcp://host:port, не выполняя esxcli." - }, - "step3": { - "title": "Открыть порт syslog в брандмауэре ESXi", - "body": "Разрешите исходящий syslog через брандмауэр ESXi, чтобы хост мог достичь Collector:" - } - }, - "as400": { - "intro": { - "title": "Принцип работы", - "body": "Коллектор AS/400 — это Linux-служба, которая напрямую подключается к вашим системам AS/400 (IBM i), извлекает записи журнала безопасности и безопасно передаёт их в UTMStack для корреляции и оповещения.", - "note": "На самом AS/400 ничего не устанавливается — Коллектор работает на Linux-хосте, имеющем сетевой доступ к вашим системам AS/400.", - "diagram": { - "source": "ваши журналы", - "edge1": "журналы", - "collector": "AS/400 Collector", - "collectorSub": "извлекает из AS/400", - "edge2": "защищённый канал", - "utmstackSub": "оповещения и корреляция" - } - }, - "install": { - "title": "Установить AS/400 Collector", - "body": "Выполните эту команду на Linux-хосте, который имеет сетевой доступ к UTMStack и вашим системам AS/400.", - "reuse": "AS/400 Collector уже установлен? Пропустите этот шаг — просто добавьте серверы в файл конфигурации на следующем шаге." - }, - "configure": { - "title": "Добавить серверы AS/400", - "body": "Отредактируйте as400-config.yaml в каталоге установки коллектора и добавьте каждую систему AS/400, которую хотите отслеживать:", - "note": "Вы можете указать несколько серверов. Коллектор отслеживает этот файл и автоматически перезагружается при сохранении — перезапуск не требуется." - }, - "journal": { - "title": "Включить аудит журналирования на AS/400", - "body": "На каждой системе AS/400 убедитесь, что журнал аудита безопасности QAUDJRN активен. Обратитесь к документации IBM за точными шагами — процедура различается в зависимости от версии IBM i." - }, - "uninstall": { - "title": "Необязательно — удалить Collector", - "body": "Выполните эту команду на хосте, где установлен AS/400 Collector, чтобы остановить службу и удалить все файлы." - } - }, - "bitdefender": { - "intro": { - "title": "Принцип работы", - "body": "UTMStack подключается к Bitdefender GravityZone с использованием вашего API-ключа для настройки Event Push Service. Затем GravityZone отправляет события безопасности непосредственно в UTMStack для корреляции и оповещения.", - "diagram": { - "source": "события конечных точек", - "edge": "Event Push Service", - "utmstackSub": "оповещения и корреляция" - }, - "note": "На GravityZone ничего не устанавливается — UTMStack регистрирует себя в качестве адресата push-уведомлений с использованием API-учётных данных только для чтения." - }, - "whitelist": { - "title": "Добавить IP-адреса Bitdefender в белый список", - "body": "Следующие IP-адреса Bitdefender GravityZone должны быть разрешены в вашем брандмауэре на порту 8000, чтобы Event Push Service мог достичь UTMStack:", - "note": "Добавьте эти IP-адреса в ваш брандмауэр или группу безопасности перед завершением настройки." - }, - "apiSection": "Получить учётные данные API", - "api": { - "myAccount": { - "title": "Открыть «Мой аккаунт»", - "body": "В консоли Bitdefender GravityZone нажмите My Account." - }, - "accessUrl": { - "title": "Записать Access URL", - "body": "Прокрутите вниз до раздела Control Center API и сохраните Access URL — он понадобится при заполнении формы учётных данных ниже. Затем откройте раздел API-ключей и нажмите Add в верхней части таблицы." - }, - "createKey": { - "title": "Создать API-ключ", - "body": "Введите описание для API-ключа, выберите параметр Event Push Service API и нажмите Save. Скопируйте сгенерированный ключ." - } - }, - "companySection": "Получить идентификаторы компаний", - "company": { - "myCompany": { - "title": "Открыть «Моя компания»", - "body": "В консоли GravityZone нажмите My Company." - }, - "licensing": { - "title": "Записать идентификаторы компаний", - "body": "Откройте раздел Licensing и сохраните идентификаторы компаний, которые хотите отслеживать — введите их через запятую в форме учётных данных ниже." - } - }, - "credentials": { - "title": "Ввести учётные данные", - "body": "Введите URL доступа, API-ключ, публичный IP-адрес UTMStack (на который GravityZone будет отправлять события) и идентификаторы компаний для мониторинга. UTMStack проверяет учётные данные перед сохранением." - }, - "fields": { - "accessUrl": { - "label": "URL доступа GravityZone" - }, - "connectionKey": { - "label": "API-ключ" - }, - "utmPublicIP": { - "label": "Публичный IP-адрес UTMStack" - }, - "companyIds": { - "label": "Идентификаторы компаний (через запятую)" - } - } - }, - "eset": { - "source": "ESET Protect", - "step1": { - "title": "Включите обработчик ESET на Collector", - "body": "На хосте, где установлен Collector, выполните следующую команду для запуска syslog-обработчика ESET:", - "note": "Чтобы использовать TCP вместо UDP, замените udp на tcp в приведённой выше команде." - }, - "console": { - "moreMenu": { - "title": "Откройте меню «Дополнительно»", - "body": "На боковой панели консоли ESET Protect нажмите меню Дополнительно." - }, - "serverConfig": { - "title": "Откройте настройки сервера", - "body": "В разделе «Дополнительно» откройте раздел Настройки сервера (конфигурация сервера)." - }, - "advanced": { - "title": "Разверните расширенные настройки", - "body": "Нажмите Расширенные настройки, чтобы открыть полный список параметров конфигурации." - }, - "syslog": { - "title": "Настройте Syslog-сервер", - "body": "Прокрутите до Syslog server, включите Export logs to Syslog и укажите в качестве назначения хост Collector на порту {{port}} (UDP). ESET отправляет LEEF/syslog, который Collector принимает как тип данных antivirus-esmc-eset." - } - } - }, - "kaspersky": { - "source": "Kaspersky Security", - "step1": { - "title": "Включите обработчик Kaspersky на Collector", - "body": "На хосте, где установлен Collector, выполните следующую команду для запуска syslog-обработчика Kaspersky:", - "note": "Чтобы использовать TCP вместо UDP, замените udp на tcp в приведённой выше команде." - }, - "console": { - "consoleSettings": { - "title": "Откройте «Настройки консоли» → «Интеграция»", - "body": "На боковой панели Kaspersky Security Center откройте Настройки консоли и нажмите подменю Интеграция." - }, - "siem": { - "title": "Откройте настройки интеграции SIEM", - "body": "В разделе «Интеграция» выберите SIEM и нажмите ссылку Настройки, чтобы открыть конфигурацию экспорта." - }, - "configure": { - "title": "Настройте экспорт SIEM", - "body": "Включите экспорт и настройте Kaspersky для отправки событий в формате Splunk (CEF) на хост Collector через порт {{port}} (UDP). Collector принимает их как тип данных antivirus-kaspersky." - } - } - }, - "sophos": { - "intro": { - "title": "Sophos Central — API Plugin", - "body": "Sophos Central предоставляет защищённые API для получения данных о событиях и предупреждениях. UTMStack подключается к этим API для централизованного мониторинга и повышения видимости безопасности — агент или Collector не требуется.", - "diagram": { - "source": "Sophos Central API", - "edge": "HTTPS API", - "utmstackSub": "Приём и корреляция" - }, - "note": "UTMStack опрашивает Sophos Central API по расписанию. Убедитесь, что создаваемые ниже учётные данные API имеют доступ на чтение событий и предупреждений." - }, - "apiSection": "Создание учётных данных API в Sophos Central", - "steps": { - "apiCredentials": { - "title": "Откройте управление учётными данными API", - "body": "В Sophos Central Admin перейдите в Global Settings → API Credentials Management." - }, - "addCredential": { - "title": "Создайте новые учётные данные", - "body": "Нажмите Add Credential. Укажите Name и Description, выберите подходящую Role, затем нажмите Add." - }, - "copyIds": { - "title": "Скопируйте Client ID и Client Secret", - "body": "Скопируйте Client ID и Client Secret и сохраните в надёжном месте.", - "secretNote": "Client Secret отображается только один раз. Сохраните его в надёжном месте, не закрывая это диалоговое окно." - } - }, - "credentialsSection": "Подключение к UTMStack", - "credentials": { - "title": "Добавьте учётные данные Sophos Central", - "body": "Введите только что созданные учётные данные. Вы можете добавить несколько учётных записей Sophos, нажав «Добавить группу конфигурации»." - }, - "fields": { - "clientId": { - "label": "Client ID" - }, - "apiKey": { - "label": "Client Secret / API-ключ" - } - } + "alertingRules": { + "title": "Правила оповещений", + "subtitle": "Правила корреляции, превращающие события в оповещения. Включайте, настраивайте или создавайте свои.", + "new": "Новое правило", + "refresh": "Обновить", + "empty": "Нет подходящих правил.", + "loadError": "Не удалось загрузить правила.", + "retry": "Повторить", + "deleteConfirm": "Удалить правило «{{name}}»?", + "adversary": { + "origin": "Источник", + "target": "Цель" }, - "webroot": { - "sections": { - "login": { - "title": "1 · Войдите в консоль управления", - "body": "Войдите в консоль управления Webroot. Она открывается на вкладке Sites." - }, - "openSettings": { - "title": "2 · Откройте «Настройки»", - "body": "Перейдите на вкладку Settings." - }, - "apiAccess": { - "title": "3 · Откройте доступ к API", - "body": "На вкладке Subscriptions нажмите вкладку API Access." - }, - "createCredential": { - "title": "4 · Создайте клиентские учётные данные", - "body": "Нажмите New и заполните поля Name и Description. Ознакомьтесь с соглашением SecureAnywhere Business Solution и Unity API, затем нажмите Create." - }, - "noteClientSecret": { - "title": "5 · Скопируйте Client ID и секрет клиента", - "body": "Сохраните Client ID из списка и Client Secret, который отображается только один раз. Нажмите «I have made note of the client secret» для подтверждения." - }, - "fillForm": { - "title": "6 · Заполните форму", - "body": "Укажите Client ID и Client Secret в UTMStack. При необходимости вы можете добавить несколько групп конфигурации Webroot." - }, - "activate": { - "title": "7 · Активация", - "body": "Активируйте модуль UTMStack, чтобы начать получать события Webroot." - } - } - }, - "sentinelOne": { - "source": "SentinelOne", - "step1": { - "title": "Включите обработчик SentinelOne на Collector", - "body": "На хосте, где установлен Collector, выполните следующую команду для запуска syslog-обработчика SentinelOne. SentinelOne передаёт CEF по TCP:", - "note": "Для зашифрованного канала используйте tls вместо tcp (предварительно загрузите сертификаты на Collector)." - }, - "console": { - "settings": { - "title": "Откройте настройки SentinelOne", - "body": "На боковой панели консоли управления SentinelOne нажмите меню Настройки." - }, - "syslog": { - "title": "Настройте интеграцию Syslog", - "body": "Перейдите в Integrations → Syslog и включите. Укажите хост {{host}} и порт {{port}}, оставьте формат CEF, нажмите Test для проверки соединения, затем Save." - } - } - }, - "office365": { - "intro": { - "title": "Как это работает", - "body": "UTMStack подключается к Microsoft 365 с помощью зарегистрированного приложения Azure AD и опрашивает Office 365 Management Activity API для получения событий аудита и безопасности. Агент в вашем тенанте не устанавливается.", - "diagram": { - "source": "события аудита и безопасности", - "edge": "Management API", - "utmstackSub": "корреляция и оповещения" - }, - "note": "UTMStack требует доступа к API только для чтения — разрешения на запись не запрашиваются." - }, - "appSection": "Регистрация приложения Azure", - "steps": { - "azurePortal": { - "title": "Откройте Microsoft Entra ID", - "body": "Откройте Azure Portal (portal.azure.com) и нажмите Microsoft Entra ID." - }, - "appRegistrations": { - "title": "Перейдите в «Регистрации приложений»", - "body": "В левом меню нажмите Регистрации приложений." - }, - "registerApp": { - "title": "Зарегистрируйте новое приложение", - "body": "Нажмите Новая регистрация. Введите имя UTMStack O365 Agent, выберите Учётные записи только в этом каталоге организации (один клиент) и нажмите Зарегистрировать." - }, - "clientSecret": { - "title": "Создайте секрет клиента", - "body": "Перейдите в Сертификаты и секреты → Новый секрет клиента. Добавьте описание, установите срок действия 730 дней (24 месяца) и нажмите Добавить.", - "copyNote": "Немедленно скопируйте значение секрета — оно отображается только один раз и впоследствии недоступно." - }, - "apiPermissions": { - "title": "Добавьте разрешения Office 365 Management API", - "body": "Перейдите в Разрешения API → Добавить разрешение и найдите Office 365 Management APIs." - }, - "activityFeed": { - "title": "Предоставьте разрешения ActivityFeed", - "body": "Выберите Разрешения приложения и добавьте ActivityFeed.Read и ActivityFeed.ReadDlp. Нажмите Предоставить согласие администратора и подтвердите." - }, - "graphPermissions": { - "title": "Добавьте разрешения Microsoft Graph", - "body": "Вернитесь в Добавить разрешение и нажмите Microsoft Graph." - }, - "delegatedPermissions": { - "title": "Добавьте делегированные разрешения SecurityAlert", - "body": "Выберите Делегированные разрешения и добавьте SecurityAlert.Read.All и SecurityAlert.ReadWrite.All. Нажмите Предоставить согласие администратора и подтвердите." - }, - "appPermissions": { - "title": "Добавьте разрешения приложения SecurityAlert", - "body": "Выберите Разрешения приложения и добавьте SecurityAlert.Read.All и SecurityAlert.ReadWrite.All. Нажмите Предоставить согласие администратора и подтвердите." - }, - "noteIds": { - "title": "Скопируйте идентификаторы приложения", - "body": "Перейдите в раздел Обзор приложения и скопируйте Идентификатор приложения (клиента) и Идентификатор каталога (тенанта). Также потребуется значение секрета, скопированное на шаге 4." - } - }, - "credentialsSection": "Учётные данные", - "credentials": { - "title": "Подключите тенант Microsoft 365", - "body": "Введите данные из шагов выше. UTMStack проверяет учётные данные перед сохранением. Вы можете добавить несколько групп конфигурации." - }, - "fields": { - "tenantId": { - "label": "Идентификатор тенанта (Directory ID)" - }, - "clientId": { - "label": "Client ID (Application ID)" - }, - "clientSecret": { - "label": "Client Secret" - }, - "cloudEnv": { - "label": "Облачная среда (необязательно)", - "hint": "Commercial (по умолчанию), GCC, GCCHigh или DoD" - } - } - }, - "github": { - "source": "GitHub", - "step1": { - "title": "Включить прослушиватель webhook GitHub на Collector", - "body": "На хосте, где установлен Collector, выполните эту команду, чтобы открыть прослушиватель webhook HTTPS для GitHub:", - "tokenNote": "Терминал выведет секретный токен — скопируйте его немедленно. Он больше не будет показан." - }, - "certWarning": { - "title": "GitHub требует TLS-сертификат, подписанный центром сертификации", - "body": "GitHub доставляет вебхуки только на конечные точки HTTPS с сертификатом, выданным публичным центром сертификации (самоподписанные сертификаты отклоняются). Убедитесь, что хост Collector имеет действующий доменный сертификат до регистрации вебхука." - }, - "step2": { - "title": "Зарегистрировать вебхук в GitHub", - "body": "В вашем репозитории или организации перейдите в Settings → Webhooks → Add webhook и заполните форму:", - "payloadUrl": "URL полезной нагрузки", - "contentType": "Тип содержимого", - "secret": "Секрет", - "secretHint": "Вставьте токен, выведенный Collector на предыдущем шаге.", - "events": "Какие события", - "eventsHint": "Отправлять всё — или выбрать определённые типы событий." - } - }, - "salesforce": { - "sections": { - "openSetup": { - "title": "1 · Открыть Setup", - "body": "Перейдите в Setup и выберите «Setup for the current app» в правом верхнем углу экрана." - }, - "appManager": { - "title": "2 · Открыть App Manager", - "body": "Введите «App Manager» в строке быстрого поиска и выберите App Manager." - }, - "newConnectedApp": { - "title": "3 · Создать новое Connected App", - "body": "На экране Lightning Experience App Manager нажмите «New Connected App» и заполните поля." - }, - "oauthSettings": { - "title": "4 · Включить OAuth Settings", - "body": "В разделе «API (Enable OAuth Settings)» установите флажок «Enable OAuth Settings» и укажите https://login.salesforce.com/services/oauth2/success в качестве Callback URL." - }, - "oauthScopes": { - "title": "5 · Добавить OAuth scopes", - "body": "Выберите «Access Connect REST API resources (chatter_api)» в разделе Selected OAuth Scopes." - }, - "save": { - "title": "6 · Сохранить", - "body": "Сохраните изменения и нажмите Continue на следующем экране." - }, - "manageConsumer": { - "title": "7 · Открыть Manage Consumer Details", - "body": "Внутри Connected App перейдите в «API (Enable OAuth Settings)» и нажмите «Manage Consumer Details» рядом с Consumer Key и Secret." - }, - "copyCredentials": { - "title": "8 · Скопировать Consumer Key и Secret", - "body": "Подтвердите личность. Consumer Key и Consumer Secret отображаются в разделе «Consumer Details». Скопируйте оба с помощью кнопки Copy." - }, - "fillForm": { - "title": "9 · Заполнить форму", - "body": "Укажите Consumer Key, Consumer Secret, имя пользователя и пароль Salesforce в UTMStack." - }, - "activate": { - "title": "10 · Активировать", - "body": "Активируйте модуль UTMStack, чтобы события Salesforce начали поступать." - } - } + "state": { + "active": "Активно", + "inactive": "Неактивно" }, - "iis": { - "sections": { - "enableModule": { - "title": "1 · Включить модуль IIS Filebeat", - "body": "На хосте агента UTMStack выполните:\ncd \"C:\\Program Files\\UTMStack\\UTMStack Agent\\beats\\filebeat\\\" && filebeat modules enable iis" - }, - "configureModule": { - "title": "2 · Настроить модуль IIS", - "body": "Отредактируйте C:\\Program Files\\UTMStack\\UTMStack Agent\\beats\\filebeat\\modules.d\\iis.yml, как показано ниже, чтобы указать каталоги журналов IIS для отправки." - }, - "activate": { - "title": "3 · Активировать", - "body": "Активируйте модуль UTMStack, чтобы события IIS начали поступать." - } - } + "owner": { + "system": "Системное", + "custom": "Пользовательское" }, - "filebeat": { - "sections": { - "installRsyslog": { - "title": "1 · Установить rsyslog", - "body": "Убедитесь, что rsyslog установлен на хосте. Используйте менеджер пакетов вашего дистрибутива (apt, dnf, yum)." - }, - "configureRsyslog": { - "title": "2 · Настроить rsyslog для пересылки в UTMStack", - "body": "Отредактируйте /etc/rsyslog.conf (или файл в /etc/rsyslog.d/) и добавьте правило пересылки, направляющее трафик на агент UTMStack по UDP или TCP на порту 514." - }, - "restartRsyslog": { - "title": "3 · Перезапустить rsyslog", - "body": "Перезапустите службу rsyslog: sudo systemctl restart rsyslog" - }, - "enableCollector": { - "title": "4 · Включить сборщик журналов Linux", - "body": "Включите сборщик журналов и интеграцию Linux Logs в конфигурационном файле там, где установлен агент UTMStack." - } - } + "toolbar": { + "search": "Поиск правил…", + "allCategories": "Все категории", + "allAdversaries": "Все стороны", + "allStates": "Все состояния", + "allOwners": "Все источники", + "allDataTypes": "Все типы" }, - "json": { - "sections": { - "overview": { - "title": "1 · Использовать конечную точку приёма HTTP/JSON", - "body": "UTMStack принимает произвольные JSON-события по HTTPS. Отправьте POST-запрос со списком событий; UTMStack разберёт их и направит через настроенный парсер." - }, - "auth": { - "title": "2 · Аутентификация с помощью токена федерации", - "body": "Получите токен федерации в Settings → Connection Key и передайте его как Bearer-токен в заголовке Authorization." - } - }, - "endpoint": { - "title": "Конечная точка приёма JSON", - "hint": "Используйте этот формат запроса из вашего приложения или задания cron. Токен — это ключ федерации из Settings → Connection Key." - } - }, - "ldap": { - "sections": { - "openServerManager": { - "title": "1 · Открыть Server Manager", - "body": "На контроллере домена AD откройте Server Manager." - }, - "addRoles": { - "title": "2 · Добавить роли и компоненты", - "body": "Выберите «Add roles and features» в меню Manage." - }, - "selectCertServices": { - "title": "3 · Выбрать Active Directory Certificate Services", - "body": "На шаге Server Roles выберите Active Directory Certificate Services." - }, - "installServices": { - "title": "4 · Установить службу роли Центра сертификации", - "body": "На шаге Role Services выберите Certificate Authority и завершите работу мастера." - }, - "configureAdCs": { - "title": "5 · Настроить AD CS", - "body": "После установки нажмите на уведомление для настройки AD CS и выберите Certificate Authority в качестве службы роли для настройки." - }, - "pickCaType": { - "title": "6 · Выбрать тип ЦС", - "body": "Выберите Enterprise CA → Root CA → Create a new private key." - }, - "setValidity": { - "title": "7 · Установить срок действия сертификата", - "body": "Установите срок действия, соответствующий требованиям вашей организации (обычно 5 лет)." - }, - "confirm": { - "title": "8 · Подтвердить и установить", - "body": "Проверьте настройки и нажмите Configure для завершения." - }, - "restart": { - "title": "9 · Перезапустить контроллер домена", - "body": "Перезапустите контроллер домена, чтобы LDAPS стал доступен на TCP 636." - }, - "activate": { - "title": "10 · Активировать", - "body": "Активируйте модуль UTMStack, чтобы события аудита AD начали поступать." - } - } - }, - "oracle": { - "source": "Сервер Oracle DB", - "step1": { - "title": "Включить интеграцию Oracle на Collector", - "body": "На сервере, где установлен Collector, выполните следующую команду, чтобы начать прослушивание журналов Oracle:", - "note": "Collector начнёт получать события syslog от Oracle на порту 7021." - }, - "step2": { - "title": "Настроить rsyslog на сервере Oracle", - "body": "Создайте файл конфигурации rsyslog:", - "editBody": "Откройте файл в предпочтительном редакторе и добавьте следующую конфигурацию. Замените BASEDIR путём установки Oracle (например, /u01/app/oracle), а — IP-адресом или именем хоста Collector:", - "note": "Используйте @@:7021 вместо @, если предпочитаете доставку по TCP." - }, - "step3": { - "title": "Перезапустить rsyslog", - "body": "Примените новую конфигурацию, перезапустив службу rsyslog:" - }, - "step4": { - "title": "Проверить конфигурацию", - "body": "Отправьте тестовые сообщения журнала, чтобы убедиться, что UTMStack получает события от всех трёх источников журналов Oracle:", - "note": "Откройте Log Explorer и найдите текст тестового сообщения выше, чтобы подтвердить его получение." - } - }, - "vulnerabilities": { - "sections": { - "overview": { - "title": "1 · О сканере уязвимостей", - "body": "Модуль уязвимостей UTMStack сканирует активы, обнаруженные через модуль Asset Management, и сопоставляет их отпечатки с базой данных CVE." - }, - "scope": { - "title": "2 · Определить область сканирования", - "body": "Используйте модуль Asset Management для регистрации хостов, которые необходимо сканировать. Сканер уязвимостей будет периодически проверять их." - }, - "activate": { - "title": "3 · Активировать", - "body": "Активируйте модуль UTMStack для запуска сканирования." - } - } + "table": { + "name": "Правило", + "category": "Категория", + "technique": "Техника", + "adversary": "Сторона", + "impact": "Влияние", + "active": "Активно", + "dataTypes": "Типы данных", + "selectAll": "Выбрать все", + "selectRow": "Выбрать {{name}}" }, - "assetScanner": { - "sections": { - "overview": { - "title": "1 · Об управлении активами", - "body": "Модуль Asset Management обнаруживает и инвентаризирует хосты, программное обеспечение и сервисы в вашей сети." - }, - "agentRequirement": { - "title": "2 · Требования к агенту", - "body": "Обнаружение активов использует агенты UTMStack, работающие на хостах Linux, Windows или macOS. Установите агент на системы, которые необходимо инвентаризировать." - }, - "activate": { - "title": "3 · Активировать", - "body": "Активируйте модуль UTMStack, чтобы начать обнаружение активов." - } - } + "export": { + "all": "Экспортировать все", + "selected": "Экспорт ({{count}})", + "error": "Не удалось экспортировать правила" }, - "fileIntegrity": { - "sections": { - "enableAuditPolicy": { - "title": "1 · Включить аудит доступа к объектам", - "body": "На хосте Windows откройте Group Policy → Computer Configuration → Windows Settings → Security Settings → Advanced Audit Policy Configuration → Object Access и включите \"Audit File System\"." - }, - "configureFolderAuditing": { - "title": "2 · Настроить аудит папок", - "body": "Для каждой папки, которую необходимо контролировать, откройте Properties → Security → Advanced → Auditing и добавьте запись аудита для нужных субъектов и типов доступа." - }, - "verifyEvents": { - "title": "3 · Проверить появление событий в журнале безопасности", - "body": "Откройте Event Viewer и убедитесь, что при обращении к аудируемым объектам генерируются события 4663/4670." - }, - "activate": { - "title": "4 · Активировать", - "body": "Активируйте модуль UTMStack, чтобы начали поступать события целостности файлов." - } - } + "view": { + "description": "Описание", + "details": "Детали", + "impact": "Влияние (К·Ц·Д)", + "dataTypes": "Типы данных", + "updated": "Обновлено", + "relPath": "Путь", + "definition": "Условие (CEL)", + "correlationSteps": "Шаги корреляции", + "correlation": "Корреляция", + "groupBy": "Группировать по", + "deduplicateBy": "Дедупликация по", + "references": "Ссылки" }, - "socAi": { - "sections": { - "overview": { - "title": "1 · О SOC AI", - "body": "SOC AI расширяет UTMStack аналитиком на основе LLM, который обобщает оповещения и предлагает дальнейшие шаги. Работает с выбранным вами провайдером." - }, - "chooseProvider": { - "title": "2 · Выбрать провайдера", - "body": "Выберите провайдера — OpenAI, Anthropic, Azure OpenAI, Google Gemini, Ollama, Mistral, DeepSeek, Groq или совместимый с OpenAI пользовательский endpoint." - }, - "configureCredentials": { - "title": "3 · Настроить учётные данные", - "body": "Укажите API-ключ, а также (при необходимости) название модели и URL endpoint." - }, - "activate": { - "title": "4 · Активировать", - "body": "Активируйте модуль UTMStack, чтобы SOC AI начал обрабатывать оповещения." - } - } - }, - "utmstack": { - "intro": { - "title": "Как это работает", - "body": "Эта интеграция обеспечивает самомониторинг вашего развёртывания UTMStack. Лёгкий коллектор, установленный на хосте UTMStack, отслеживает журналы контейнеров Docker самой платформы и передаёт их обратно в UTMStack для корреляции и создания оповещений.", - "diagram": { - "source": "Журналы Docker", - "sourceSub": "Контейнеры UTMStack", - "edge1": "отслеживание", - "collector": "Коллектор", - "collectorSub": "на хосте", - "edge2": "приём", - "utmstackSub": "Корреляция и оповещения" - } - }, - "requirements": { - "title": "Работает только на хосте UTMStack", - "body": "Эта интеграция может быть установлена только на экземпляр UTMStack под управлением Ubuntu или дистрибутива семейства Red Hat. Установите коллектор непосредственно на сервер UTMStack." - }, - "install": { - "title": "Установить коллектор", - "body": "На хосте UTMStack выберите операционную систему и выполните приведённую ниже команду для загрузки и установки коллектора самомониторинга:", - "sensitiveWarning": "Эта команда содержит конфиденциальный токен подключения. Обращайтесь с ним как с паролем и не передавайте его третьим лицам." - }, - "after": { - "title": "Что вы увидите после установки", - "item1": "Коллектор регистрируется и отображается в разделе Data sources.", - "item2": "Журналы контейнеров UTMStack начинают поступать в течение минуты.", - "item3": "События становятся доступны для поиска в Log Explorer в типе данных utmstack." - }, - "uninstall": { - "title": "Удалить коллектор", - "body": "Чтобы удалить коллектор самомониторинга с хоста UTMStack, выполните:" - } - }, - "windowsFaa": { - "sections": { - "enableAuditPolicy": { - "title": "1 · Включить аудит доступа к объектам", - "body": "На хосте Windows откройте Group Policy → Computer Configuration → Windows Settings → Security Settings → Advanced Audit Policy Configuration → Object Access и включите \"Audit File System\"." - }, - "configureFolderAuditing": { - "title": "2 · Настроить аудит папок", - "body": "Для каждой папки, которую необходимо контролировать, откройте Properties → Security → Advanced → Auditing и добавьте запись аудита для нужных субъектов и типов доступа." - }, - "activate": { - "title": "3 · Активировать", - "body": "Активируйте модуль UTMStack, чтобы начали поступать события файловой активности." - } - } + "editor": { + "createTitle": "Новое правило", + "edit": "Изменить", + "delete": "Удалить", + "export": "Экспортировать", + "cancel": "Отмена", + "save": "Сохранить", + "metadata": "Метаданные", + "name": "Название", + "confidentiality": "Конфиденциальность", + "integrity": "Целостность", + "availability": "Доступность", + "dataTypes": "Типы данных", + "dataTypesHint": "через запятую", + "activeOnSave": "Активно", + "definitionSection": "Определение", + "where": "Условие (CEL)", + "whereHint": "Выражение CEL, вычисляемое для каждого события", + "correlationSteps": "Шаги корреляции", + "correlationStepsHint": "JSON-массив", + "jsonArray": "JSON-массив", + "nameRequired": "Название обязательно", + "definitionRequired": "Условие обязательно", + "invalidJson": "В поле определения некорректный JSON", + "addStep": "Добавить шаг корреляции", + "step": "Шаг {{n}}", + "removeStep": "Удалить шаг", + "indexPattern": "Шаблон индекса", + "within": "Окно", + "count": "Количество", + "conditions": "Условия", + "field": "Поле", + "value": "Значение", + "addCondition": "Добавить условие", + "orGroup": "Группа Or {{n}}", + "addOr": "Добавить группу Or", + "removeOr": "Удалить", + "fieldsHint": "имена полей", + "referencesHint": "URL", + "visual": "Визуально", + "code": "Код", + "dataTypesPick": "Выбрать…", + "dataTypesSearch": "Поиск типов данных…", + "dataTypesNone": "Нет типов данных", + "visualTab": "Визуально", + "codeTab": "Код", + "yamlError": "Не удалось применить YAML: {{error}}", + "test": "Test" }, - "awsBeanstalk": { - "sections": { - "openConsole": { - "title": "1 · Открыть консоль Elastic Beanstalk", - "body": "В AWS Console откройте Elastic Beanstalk." - }, - "environment": { - "title": "2 · Открыть страницу управления окружением", - "body": "Перейдите на страницу управления окружением, которое необходимо отслеживать." - }, - "configuration": { - "title": "3 · Открыть раздел Configuration", - "body": "Выберите Configuration." - }, - "software": { - "title": "4 · Изменить конфигурацию Software", - "body": "В категории Software configuration выберите Modify." - }, - "s3LogStorage": { - "title": "5 · Включить хранение журналов в S3", - "body": "В разделе S3 log storage выберите Rotate logs для загрузки ротируемых журналов в Amazon S3." - }, - "cloudwatchStreaming": { - "title": "6 · Включить потоковую передачу CloudWatch Logs", - "body": "В разделе Instance log streaming to CloudWatch Logs включите потоковую передачу, задайте период хранения и выберите, загружать ли существующие журналы." - }, - "activate": { - "title": "7 · Активировать", - "body": "Активируйте модуль UTMStack, чтобы начали поступать события Beanstalk." - } - } + "toast": { + "activated": "Правило включено", + "deactivated": "Правило выключено", + "toggleError": "Не удалось изменить состояние правила", + "deleted": "Правило удалено", + "deleteError": "Не удалось удалить правило", + "created": "Правило создано", + "saved": "Правило сохранено", + "saveError": "Не удалось сохранить правило" }, - "awsFargate": { - "sections": { - "taskDefinition": { - "title": "1 · Обновить определение задачи", - "body": "В определении задачи для Fargate задайте logDriver как \"awslogs\" и укажите имя группы журналов." - }, - "cloudwatchLogs": { - "title": "2 · Убедиться, что CloudWatch Logs получает журналы", - "body": "Откройте консоль CloudWatch Logs и убедитесь, что группа журналов заполняется при выполнении задач." - }, - "iamPrerequisite": { - "title": "3 · Предварительное условие: IAM-пользователь", - "body": "Эта интеграция использует общие учётные данные с модулем AWS IAM User — убедитесь, что он настроен с политикой CloudWatchLogsReadOnlyAccess." - }, - "activate": { - "title": "4 · Активировать", - "body": "Активируйте модуль UTMStack, чтобы начали поступать события Fargate." - } - } + "operator": { + "filter_term": "равно (term)", + "must_not_term": "не равно (term)", + "filter_match": "совпадает (текст)", + "must_not_match": "не совпадает (текст)" }, - "awsIamUser": { - "sections": { - "iamConsole": { - "title": "1 · Открыть консоль IAM", - "body": "В консоли AWS перейдите в IAM → Users → Add users." - }, - "createUser": { - "title": "2 · Создать пользователя", - "body": "Введите имя пользователя (например, utmstack-ingest). Выберите программный доступ." - }, - "programmaticAccess": { - "title": "3 · Задать тип учётных данных", - "body": "Выберите \"Access key — Programmatic access\"." - }, - "attachPolicy": { - "title": "4 · Привязать политику чтения CloudWatch", - "body": "Привяжите управляемую AWS политику CloudWatchLogsReadOnlyAccess." - }, - "review": { - "title": "5 · Проверить пользователя", - "body": "Проверьте данные пользователя и нажмите Create user." - }, - "copyKeys": { - "title": "6 · Скопировать идентификатор ключа доступа и секрет", - "body": "Скопируйте Access key ID и Secret access key — секрет отображается только один раз." - }, - "createLogGroup": { - "title": "7 · Создать группу журналов CloudWatch", - "body": "В CloudWatch → Log groups создайте группу журналов с именем \"utmstack\" — другие интеграции AWS будут направлять данные в неё." - }, - "fillForm": { - "title": "8 · Заполнить форму", - "body": "Укажите в UTMStack ключ доступа, секрет, регион по умолчанию и имя группы журналов (например, \"utmstack\")." - }, - "activate": { - "title": "9 · Активировать", - "body": "Активируйте модуль UTMStack, чтобы начали поступать события AWS." - } - } + "where": { + "matchPrefix": "Соответствует", + "all": "всем", + "any": "любому", + "matchSuffix": "из этих условий:", + "negate": "Отрицать", + "listHint": "через запятую", + "advanced": "Это условие использует сложный CEL — измените его в режиме «Код» или соберите заново визуально.", + "and": "И", + "or": "ИЛИ" }, - "awsLambda": { - "sections": { - "iamPrerequisite": { - "title": "1 · Предварительное условие: IAM-пользователь", - "body": "Lambda использует модуль AWS IAM User — убедитесь, что эта интеграция настроена первой с политикой CloudWatchLogsReadOnlyAccess." - }, - "cloudwatchStream": { - "title": "2 · Lambda уже передаёт данные в CloudWatch Logs", - "body": "AWS Lambda автоматически публикует журналы выполнения в CloudWatch Logs в разделе /aws/lambda/. UTMStack получает данные из группы журналов, настроенной при создании IAM-пользователя." - }, - "activate": { - "title": "3 · Активировать", - "body": "Активируйте модуль UTMStack, чтобы начали поступать события Lambda." - } - } + "celOp": { + "exists": "существует", + "equals": "равно", + "equalsIgnoreCase": "равно (без регистра)", + "contains": "содержит", + "oneOf": "одно из", + "containsAll": "содержит все", + "startsWith": "начинается с", + "endsWith": "заканчивается на", + "regexMatch": "regex", + "lessThan": "<", + "lessOrEqual": "≤", + "greaterThan": ">", + "greaterOrEqual": "≥", + "inCIDR": "в CIDR", + "isHour": "час равен", + "isMinute": "минута равна", + "isDayOfWeek": "день недели", + "isWeekend": "выходной", + "isWorkDay": "рабочий день", + "isBetweenTime": "время между" }, - "awsSqlServer": { - "sections": { - "openRds": { - "title": "1 · Открыть консоль Amazon RDS", - "body": "Откройте https://console.aws.amazon.com/rds/." - }, - "pickDb": { - "title": "2 · Выбрать экземпляр БД", - "body": "На панели навигации выберите Databases и укажите экземпляр БД, который необходимо отслеживать." - }, - "modify": { - "title": "3 · Изменить экземпляр", - "body": "Выберите Modify." - }, - "logExports": { - "title": "4 · Включить экспорт журналов", - "body": "В разделе Log exports выберите Error log и Agent log для публикации в CloudWatch Logs." - }, - "apply": { - "title": "5 · Применить изменения", - "body": "Нажмите «Continue», затем «Modify DB Instance» на странице сводки." - }, - "activate": { - "title": "6 · Активировать", - "body": "Активируйте модуль UTMStack, чтобы начать получать события SQL Server." - } - } + "import": { + "button": "Импорт", + "error": "Сбой импорта", + "resultTitle": "Результаты импорта", + "approved": "Одобрено", + "rejected": "Отклонено", + "done": "Готово" }, - "awsPostgresql": { - "sections": { - "openRds": { - "title": "1 · Открыть консоль Amazon RDS", - "body": "Откройте https://console.aws.amazon.com/rds/." - }, - "pickDb": { - "title": "2 · Выбрать экземпляр БД", - "body": "На панели навигации выберите «Databases» и укажите экземпляр БД, который нужно изменить." - }, - "logExports": { - "title": "3 · Включить экспорт журналов", - "body": "В разделе «Log exports» выберите журнал PostgreSQL для публикации в CloudWatch Logs." - }, - "apply": { - "title": "4 · Применить изменения", - "body": "Нажмите «Continue», затем «Modify DB Instance» на странице сводки." - }, - "activate": { - "title": "5 · Активировать", - "body": "Активируйте модуль UTMStack, чтобы начать получать события PostgreSQL." - } - } + "test": "Test" + }, + "regexPatterns": { + "title": "Регулярные выражения", + "subtitle": "Многоразовые регулярные выражения, на которые ссылаются фильтры разбора.", + "new": "Новый шаблон", + "search": "Поиск шаблонов…", + "refresh": "Обновить", + "view": "Просмотр", + "system": "Системный", + "user": "Пользовательский", + "loading": "Загрузка шаблонов…", + "loadError": "Не удалось загрузить шаблоны.", + "retry": "Повторить", + "empty": "Нет шаблонов для этого представления.", + "tabs": { + "all": "Все", + "system": "Системные", + "user": "Пользовательские" }, - "awsTrafficMirror": { - "sections": { - "createTarget": { - "title": "1 · Создать целевой объект зеркалирования трафика", - "body": "В консоли VPC создайте Traffic Mirror Target, указывающий на сетевой интерфейс виртуальной машины агента UTMStack." - }, - "createFilter": { - "title": "2 · Создать фильтр зеркалирования трафика", - "body": "Создайте Traffic Mirror Filter и добавьте правила входящего/исходящего трафика для протоколов, которые нужно зеркалировать (например, весь TCP, весь UDP)." - }, - "createSession": { - "title": "3 · Создать сессию зеркалирования трафика", - "body": "Создайте Traffic Mirror Session, связывающую каждый исходный сетевой интерфейс с созданными целевым объектом и фильтром." - }, - "iamPrerequisite": { - "title": "4 · Предварительное условие: пользователь IAM", - "body": "Убедитесь, что модуль AWS IAM User также настроен, чтобы UTMStack мог при необходимости читать журналы VPC Flow Logs." - }, - "activate": { - "title": "5 · Активировать", - "body": "Активируйте модуль UTMStack, чтобы начать разбор зеркалированного трафика." - } - } - }, - "forwarder": { - "intro": { - "title": "Принцип работы", - "body": "Журналы передаются от {{source}} в UTMStack Collector, который безопасно пересылает их в UTMStack для корреляции и оповещений. На {{source}} ничего не устанавливается — Collector достаточно запустить на одном из хостов вашей сети." - }, - "diagram": { - "sourceSub": "ваши журналы", - "forwarder": "Collector", - "forwarderSub": "слушает на {{port}}", - "utmstack": "UTMStack", - "utmstackSub": "оповещения и корреляция", - "flow1": "журналы", - "flow2": "защищённо" - }, - "noInstall": "На {{source}} ничего не устанавливается — нужно лишь перенаправить его журналы в Collector.", - "install": { - "title": "Установить UTMStack Collector", - "body": "Collector — это Linux-служба, которая принимает журналы с ваших устройств и отправляет их в UTMStack. Один Collector обрабатывает несколько интеграций одновременно.", - "reuse": "Collector уже запущен? Пропустите этот шаг — укажите {{source}} хост и порт существующего Collector, как показано ниже." - }, - "tls": { - "title": "Дополнительно — Включить шифрование TLS", - "intro": "По умолчанию прослушиватель принимает нешифрованный TCP/UDP. Чтобы зашифровать трафик syslog при передаче, сначала загрузите файлы сертификатов, затем повторно включите прослушиватель с протоколом tls.", - "step1": "1 · Загрузить сертификат и ключ (один раз на Collector)", - "step1Note": "Дополнительный сертификат CA можно передать третьим аргументом. Если его опустить, в роли CA будет использован конечный сертификат.", - "step2": "2 · Повторно включить прослушиватель с TLS" - }, - "httpsCerts": { - "title": "Загрузите TLS-сертификат на Collector", - "body": "Эта интеграция использует HTTPS-прослушиватель на порту {{port}}, поэтому перед её включением на Collector необходимо загрузить сертификат и ключ:" - }, - "uninstall": { - "title": "Дополнительно — Удалить Collector", - "body": "Выполните эту команду на хосте, где установлен Collector, чтобы остановить службу и удалить все её файлы." - }, - "instanceHeader": { - "title": "Заголовок авторизации", - "body": "Включайте этот заголовок Authorization в каждый запрос, отправляемый на инстанс. Секрет API-ключа отображается только один раз при его создании — скопируйте его тогда и вставьте вместо заполнителя ниже.", - "tabSimple": "Одиночный", - "tabBatch": "Пакетный" - }, - "manualCommand": { - "title": "Optional — Enable via the command line instead", - "intro": "Prefer the terminal? SSH into the Collector host and run the command below — it matches whatever protocol and port you have selected above.", - "certStep": "1 · Load your certificate and key (once per Collector)", - "enableStep": "2 · Enable the integration" - } - }, - "aix": { - "source": "Сервер AIX", - "step1": { - "title": "Включить прослушиватель AIX на Collector", - "body": "На хосте с установленным Collector выполните эту команду, чтобы открыть прослушиватель журналов AIX:", - "note": "Чтобы использовать TCP вместо UDP, замените udp на tcp в команде выше." - }, - "step2": { - "title": "Настроить AIX для пересылки журналов", - "body": "На вашей системе AIX настройте службу syslog для перенаправления журналов на хост Collector через порт {{port}}. Обратитесь к документации IBM за точным синтаксисом — он различается в зависимости от версии AIX." - } - }, - "deceptivebytes": { - "source": "Deceptive Bytes", - "step1": { - "title": "Включить прослушиватель Deceptive Bytes на Collector", - "body": "На хосте с установленным Collector выполните эту команду, чтобы открыть прослушиватель syslog Deceptive Bytes:", - "note": "Чтобы использовать TCP вместо UDP, замените udp на tcp в команде выше." - }, - "step2": { - "title": "Настроить Deceptive Bytes для пересылки журналов", - "body": "В консоли управления Deceptive Bytes настройте пересылку syslog для отправки событий на хост Collector через порт {{port}} (UDP). Deceptive Bytes генерирует syslog в формате CEF, который Collector принимает как тип данных deceptive-bytes." - } - }, - "mikrotik": { - "source": "Маршрутизатор MikroTik", - "step1": { - "title": "Включить прослушиватель MikroTik на Collector", - "body": "На хосте с установленным Collector выполните эту команду, чтобы открыть прослушиватель syslog MikroTik:", - "note": "Чтобы использовать TCP вместо UDP, замените udp на tcp в команде выше." - }, - "step2": { - "title": "Настроить MikroTik для пересылки журналов", - "body": "На маршрутизаторе MikroTik создайте удалённое действие журналирования (logging action), указывающее на хост Collector через порт {{port}}, и привяжите его к нужным темам журнала. Выполните следующее из CLI RouterOS (Terminal в Winbox):", - "note": "Также можно настроить через Winbox: System → Logging → вкладка Actions (добавить удалённое действие) → затем вкладка Rules (добавить правила, указывающие на новое действие)." - } - }, - "fortigate": { - "source": "Межсетевой экран FortiGate", - "step1": { - "title": "Включить прослушиватель FortiGate на Collector", - "body": "На хосте с установленным Collector выполните эту команду, чтобы открыть прослушиватель syslog FortiGate:", - "note": "Чтобы использовать TCP вместо UDP, замените udp на tcp в команде выше." - }, - "step2": { - "title": "Настроить FortiGate для пересылки журналов", - "body": "На FortiGate направьте syslog на хост Collector через порт {{port}}. Выполните следующее из CLI FortiOS (или используйте Log & Report → Log Settings → Syslog в GUI):", - "note": "Замените адрес сервера, если Collector запущен на другом хосте. Для нескольких коллекторов syslog используйте syslogd2/syslogd3/syslogd4." - } - }, - "fortiweb": { - "source": "FortiWeb WAF", - "step1": { - "title": "Включить прослушиватель FortiWeb на Collector", - "body": "На хосте с установленным Collector выполните эту команду, чтобы открыть прослушиватель syslog FortiWeb:", - "note": "Чтобы использовать TCP вместо UDP, замените udp на tcp в команде выше." - }, - "step2": { - "title": "Настроить FortiWeb для пересылки журналов", - "body": "На FortiWeb создайте политику syslog, указывающую на хост Collector через порт {{port}}, и включите журналирование syslog. Выполните следующее из CLI FortiWeb (или используйте Log & Report → Log Policy → Syslog Policy в GUI):", - "note": "Убедитесь, что в настройках Log & Report включена отправка нужных типов журналов (Attack, Event, Traffic) в syslog." - } - }, - "paloalto": { - "source": "Межсетевой экран Palo Alto", - "step1": { - "title": "Включить прослушиватель Palo Alto на Collector", - "body": "На хосте с установленным Collector выполните эту команду, чтобы открыть прослушиватель syslog Palo Alto:", - "note": "Чтобы использовать TCP вместо UDP, замените udp на tcp в команде выше." - }, - "step2": { - "title": "Создать профиль Syslog-сервера", - "body": "В PAN-OS перейдите в Device → Server Profiles → Syslog и добавьте профиль. Укажите адрес сервера {{host}}, транспорт UDP, порт {{port}} и формат BSD." - }, - "step3": { - "title": "Настроить пересылку журналов и выполнить Commit", - "body": "Создайте профиль Log Forwarding (Objects → Log Forwarding), который отправляет трафик, угрозы и другие типы журналов в указанный выше профиль syslog, привяжите его к правилам Security policy (Policies → Security → правило → Actions → Log Forwarding), затем выполните Commit." - } - }, - "pfsense": { - "source": "Межсетевой экран pfSense", - "step1": { - "title": "Включить прослушиватель pfSense на Collector", - "body": "На хосте с установленным Collector выполните эту команду, чтобы открыть прослушиватель syslog pfSense:", - "note": "Чтобы использовать TCP вместо UDP, замените udp на tcp в команде выше." - }, - "step2": { - "title": "Включить удалённое журналирование в pfSense", - "body": "В веб-интерфейсе pfSense перейдите в Status → System Logs → Settings. В разделе Remote Logging Options установите флажок Enable Remote Logging, укажите удалённый сервер журналов {{host}}:{{port}}, выберите журналы для отправки (или Everything) и нажмите Save." - } - }, - "sonicwall": { - "source": "Межсетевой экран SonicWall", - "step1": { - "title": "Включить прослушиватель SonicWall на Collector", - "body": "На хосте с установленным Collector выполните эту команду, чтобы открыть прослушиватель syslog SonicWall:", - "note": "Чтобы использовать TCP вместо UDP, замените udp на tcp в команде выше." - }, - "step2": { - "title": "Добавить Syslog-сервер в SonicOS", - "body": "В SonicOS перейдите в Device → Log → Syslog (на старых прошивках: Manage → Log → Syslog) и добавьте Syslog Server с адресом {{host}} и портом {{port}}. Установите Syslog Format в значение ArcSight (CEF) — UTMStack обрабатывает SonicWall в формате CEF — затем нажмите Apply." - } - }, - "sophosxg": { - "source": "Sophos Firewall", - "step1": { - "title": "Включить прослушиватель Sophos Firewall на Collector", - "body": "На хосте с установленным Collector выполните эту команду, чтобы открыть прослушиватель syslog Sophos Firewall:", - "note": "Чтобы использовать TCP вместо UDP, замените udp на tcp в команде выше." - }, - "step2": { - "title": "Добавить Syslog-сервер в Sophos Firewall", - "body": "В консоли Sophos Firewall (SFOS) перейдите в System → System services → Log settings и добавьте Syslog-сервер с адресом {{host}} и портом {{port}}. Выберите типы журналов для пересылки (firewall, IPS, ATP, web и др.) и нажмите Apply." - } - }, - "suricata": { - "source": "Suricata IDS", - "step1": { - "title": "Включить прослушиватель Suricata на Collector", - "body": "На хосте, где установлен Collector, выполните следующую команду для открытия прослушивателя Suricata:", - "note": "Чтобы использовать TCP вместо UDP, замените udp на tcp в приведённой выше команде." - }, - "step2": { - "title": "Отправить журналы Suricata EVE в syslog", - "body": "Suricata принимает данные в формате JSON (EVE). На хосте Suricata отредактируйте suricata.yaml и настройте вывод eve-log для записи в syslog:", - "note": "Затем перезапустите Suricata: sudo systemctl restart suricata" - }, - "step3": { - "title": "Пересылать syslog на Collector", - "body": "Направьте объект local5 (куда теперь пишет Suricata) на Collector. Добавьте это правило в /etc/rsyslog.d/60-utmstack-suricata.conf на хосте Suricata:", - "note": "Используйте @@ вместо @ для TCP. Затем перезапустите rsyslog: sudo systemctl restart rsyslog" - } - }, - "o365_graph": { - "intro": { - "title": "Как это работает", - "body": "UTMStack подключается к Microsoft 365 через зарегистрированное приложение Azure AD и опрашивает Microsoft Graph на события безопасности: оповещения, инциденты, аудит каталога, sign-in, обнаружения рисков, hunting-запросы и журналы аудита Purview. Агент в вашем tenant не устанавливается.", - "diagram": { - "source": "события безопасности", - "edge": "Microsoft Graph", - "utmstackSub": "корреляция и оповещения" - }, - "note": "UTMStack требует только доступа к API Graph в режиме чтения — разрешения на запись не запрашиваются." - }, - "appSection": "Регистрация приложения Azure", - "steps": { - "azurePortal": { - "title": "Откройте Microsoft Entra ID", - "body": "Откройте портал Azure (portal.azure.com) и нажмите Microsoft Entra ID." - }, - "appRegistrations": { - "title": "Перейдите к «Регистрации приложений»", - "body": "В левом меню нажмите Регистрация приложений." - }, - "registerApp": { - "title": "Зарегистрируйте новое приложение", - "body": "Нажмите Новая регистрация. Назовите его UTMStack Graph Dev, выберите Только учётные записи в этом организационном каталоге (Single-tenant) и нажмите Зарегистрировать." - }, - "clientSecret": { - "title": "Создайте секрет клиента", - "body": "Перейдите в Сертификаты и секреты → Новый секрет клиента. Добавьте описание, установите срок действия 730 дней (24 месяца) и нажмите Добавить.", - "copyNote": "Сразу скопируйте значение секрета — оно показывается только один раз и позже недоступно." - }, - "apiPermissions": { - "title": "Добавьте разрешения Microsoft Graph", - "body": "Перейдите в Разрешения API → Добавить разрешение и выберите Microsoft Graph, затем Разрешения приложения." - }, - "graphPermissions": { - "title": "Добавьте четыре разрешения Graph", - "body": "Добавьте SecurityEvents.Read.All, Directory.Read.All, AuditLog.Read.All и IdentityRiskEvent.Read.All." - }, - "adminConsent": { - "title": "Предоставьте согласие администратора", - "body": "Вернувшись в Разрешения API, нажмите Предоставить согласие администратора для {tenant} и подтвердите." - }, - "noteIds": { - "title": "Скопируйте идентификаторы приложения", - "body": "Перейдите в Обзор приложения и скопируйте Идентификатор приложения (клиента) и Идентификатор каталога (tenant). Также вам понадобится значение секрета, скопированное на шаге 4." - } - }, - "credentialsSection": "Учётные данные", - "credentials": { - "title": "Подключите ваш tenant Microsoft 365", - "body": "Введите данные из шагов выше. UTMStack проверяет учётные данные перед сохранением. Можно добавить несколько групп конфигурации." - }, - "fields": { - "tenantId": { - "label": "Идентификатор Tenant (Идентификатор каталога)" - }, - "clientId": { - "label": "Идентификатор клиента (Идентификатор приложения)" - }, - "clientSecret": { - "label": "Секрет клиента" - }, - "cloudEnv": { - "label": "Облачная среда (необязательно)", - "hint": "Commercial (по умолчанию), GCC, GCCHigh или DoD" - } - } + "cols": { + "pattern": "Шаблон", + "definition": "Определение", + "type": "Тип" + }, + "editor": { + "titleNew": "Новый шаблон", + "patternId": "ID шаблона", + "patternIdHint": "Уникальное имя, на которое ссылаются фильтры.", + "description": "Описание", + "descriptionPlaceholder": "Что распознаёт этот шаблон (необязательно)", + "definition": "Определение (regex)", + "definitionHint": "Регулярное выражение. Может ссылаться на другие шаблоны.", + "readOnly": "Системный шаблон — только чтение.", + "save": "Сохранить", + "saving": "Сохранение…", + "delete": "Удалить", + "confirmDelete": "Подтвердить удаление", + "cancel": "Отмена" + }, + "toast": { + "saved": "Шаблон сохранён", + "saveError": "Не удалось сохранить шаблон", + "deleted": "Шаблон удалён", + "deleteError": "Не удалось удалить шаблон", + "patternIdRequired": "ID шаблона обязателен", + "definitionRequired": "Определение обязательно" } - }, - "cloud": { - "howItWorksTitle": "Как это работает", - "howItWorksBody": "{{name}} работает полностью внутри UTMStack — нет необходимости развертывать агент или коллектор. Предоставьте учетные данные API только для чтения, и UTMStack будет извлекать события по расписанию, анализировать их и загружать в Log Explorer.", - "connectionTitle": "Соединение", - "noFields": "Не настроено ни одного поля соединения.", - "testConnection": "Проверить соединение", - "save": "Сохранить", - "afterTitle": "Что вы увидите после подключения", - "after1": "UTMStack выполняет первоначальную загрузку недавних событий.", - "after2": "Впоследствии события извлекаются каждые 1–5 минут (зависит от API).", - "after3": "Интеграция появляется в разделе Источники данных с текущим статусом извлечения и задержкой.", - "tenants": { - "title": "Настроенные группы конфигурации", - "empty": "Групп конфигурации пока нет. Добавьте первую ниже.", - "loading": "Загрузка групп конфигурации…", - "nameLabel": "Имя группы конфигурации", - "namePlaceholder": "напр. acme-prod", - "add": "Добавить группу конфигурации", - "update": "Обновить группу конфигурации", - "delete": "Удалить", - "edit": "Изменить", - "cancel": "Отмена", - "editing": "Редактирование: {{name}}", - "selectFile": "Выбрать файл", - "replaceFile": "Заменить файл", - "fileLoaded": "Файл загружен", - "invalidJson": "Не удалось прочитать файл как JSON.", - "createError": "Не удалось создать группу конфигурации. Повторите попытку.", - "updateError": "Не удалось обновить группу конфигурации. Повторите попытку.", - "createSuccess": "Группа конфигурации успешно создана.", - "updateSuccess": "Группа конфигурации успешно обновлена." - }, - "google": { - "sections": { - "createTopic": { - "title": "1 · Создайте тему Pub/Sub", - "body": "В консоли Google Cloud откройте Pub/Sub → Темы и создайте новую тему. UTMStack будет получать события через эту тему.", - "docLabel": "Открыть страницу тем Pub/Sub" - }, - "createSubscription": { - "title": "2 · Создайте подписку", - "body": "Внутри темы создайте подписку типа Pull. UTMStack извлекает сообщения из этой подписки." - }, - "configureSubscription": { - "title": "3 · Настройте подписку", - "body": "Задайте срок хранения сообщений в соответствии с допустимым простоем (по умолчанию 7 дней — это нормально). Оставьте срок подтверждения 10 секунд, а истечение — «Никогда»." - }, - "logsRouter": { - "title": "4 · Откройте Logs Router", - "body": "Перейдите в Logging → Logs Router и создайте новый sink. Он пересылает логи проекта в созданную выше тему Pub/Sub." - }, - "sinkDestination": { - "title": "5 · Направьте sink на тему", - "body": "Выберите Cloud Pub/Sub topic как назначение sink и выберите созданную тему. Используйте фильтры включения/исключения, чтобы ограничить, что пересылается." - }, - "serviceAccount": { - "title": "6 · Создайте сервисный аккаунт", - "body": "Откройте IAM и администрирование → Сервисные аккаунты и создайте новый сервисный аккаунт. Назначьте ему роль Pub/Sub Editor, чтобы UTMStack мог читать из подписки.", - "docLabel": "Открыть страницу сервисных аккаунтов" - }, - "serviceAccountKey": { - "title": "7 · Создайте ключ для сервисного аккаунта", - "body": "Откройте сервисный аккаунт, перейдите во вкладку Ключи и добавьте новый ключ. Выберите тип ключа JSON." - }, - "downloadKey": { - "title": "8 · Скачайте и загрузите JSON-ключ", - "body": "Сохраните JSON-файл, скачанный Google: его содержимое нужно вставить в поле «JSON-ключ сервисного аккаунта» ниже." - } - }, - "fields": { - "projectId": { - "label": "ID проекта" - }, - "subscription": { - "label": "Имя подписки" - }, - "jsonKey": { - "label": "JSON-ключ сервисного аккаунта" + }, + "parsingFilters": { + "title": "Пайплайны", + "subtitle": "YAML-пайплайны, применяемые к логам при их разборе во время приёма.", + "new": "Новый пайплайн", + "search": "Поиск пайплайнов…", + "refresh": "Обновить", + "view": "Просмотр", + "system": "Системный", + "user": "Свои", + "loading": "Загрузка пайплайнов…", + "loadError": "Не удалось загрузить пайплайны.", + "retry": "Повторить", + "empty": "Нет пайплайнов для этого вида.", + "tabs": { + "all": "Все", + "active": "Активные", + "inactive": "Неактивные", + "system": "Системные", + "user": "Свои" + }, + "cols": { + "filter": "Пайплайн", + "type": "Тип", + "active": "Активен", + "dataTypes": "Типы данных", + "order": "Порядок", + "moveUp": "Переместить вверх", + "moveDown": "Переместить вниз", + "actions": "Действия" + }, + "editor": { + "titleNew": "Новый пайплайн", + "titleEdit": "Редактировать пайплайн", + "titleSystem": "Пайплайн (системный)", + "name": "Имя", + "namePlaceholder": "Мой собственный пайплайн", + "nameHint": "Будет сохранено как {{file}}", + "namePending": "Выберите имя — оно станет именем файла.", + "content": "Содержимое (pipeline YAML)", + "contentHint": "Корректное определение в формате pipeline: YAML.", + "readOnly": "Системный пайплайн — только для чтения. Можно лишь включить или отключить.", + "save": "Сохранить", + "saving": "Сохранение…", + "delete": "Удалить", + "confirmDelete": "Подтвердить удаление", + "cancel": "Отмена", + "test": "Test" + }, + "toast": { + "saved": "Пайплайн сохранён", + "saveError": "Не удалось сохранить пайплайн", + "deleted": "Пайплайн удалён", + "deleteError": "Не удалось удалить пайплайн", + "activateError": "Не удалось изменить состояние пайплайна", + "nameRequired": "Имя обязательно", + "contentRequired": "Содержимое обязательно", + "orderError": "Не удалось изменить порядок пайплайна" + }, + "visual": { + "visualTab": "Визуально", + "codeTab": "Код", + "codeOnly": "Переключитесь на Код — это содержимое нельзя показать визуально.", + "cantParse": "Не удалось открыть визуальный редактор: {{error}}", + "dataTypes": "Типы данных", + "steps": "Шаги", + "noSteps": "Пока нет шагов.", + "addStep": "Добавить шаг:", + "removeStep": "Удалить шаг", + "moveUp": "Вверх", + "moveDown": "Вниз", + "whereHint": "необязательное условие (CEL)", + "addValue": "Добавить значение", + "addPattern": "Добавить шаблон", + "rawHint": "Этот процессор редактируется как сырой YAML.", + "rawNotMap": "Должен быть набор полей ключ: значение.", + "dataTypesPick": "Выбрать типы данных", + "dataTypesSearch": "Поиск типов данных…", + "dataTypesNone": "Нет типов данных", + "dataTypesAdd": "Добавить «{{value}}»", + "insertPattern": "Вставить regex-шаблон", + "patternSearch": "Поиск шаблонов…", + "patternNone": "Нет шаблонов", + "newPattern": "Новый шаблон…", + "createInsert": "Создать и вставить", + "patternCreated": "Шаблон «{{name}}» создан", + "patternCreateError": "Не удалось создать шаблон", + "patternIdInvalid": "ID шаблона должен начинаться с буквы или _ и содержать только буквы, цифры или _", + "patternDefRequired": "Определение обязательно", + "parameters": "Параметры", + "paramsKey": "Ключ", + "paramsValue": "Значение", + "entry": "Запись {{n}}", + "order": "порядок {{n}}", + "orderLabel": "Порядок", + "removeEntry": "Удалить запись", + "addEntry": "Добавить запись пайплайна", + "collapse": "Свернуть", + "expand": "Развернуть", + "splitHint": "Vacío equivale a un espacio por defecto — en el YAML siempre aparece como fieldSplit: \" \"." + }, + "allDataTypes": "Все типы данных", + "testPipeline": "Test pipeline" + }, + "soar": { + "title": "SOAR", + "subtitle": "Автоматические потоки реагирования: условия совпадают с алертом, команды выполняются на агенте.", + "comingSoon": "Скоро появится", + "console": { + "loading": "Загрузка агентов…", + "loadError": "Не удалось загрузить агентов.", + "pickAgent": "Выберите агента", + "pickAgentHint": "Выберите агента из списка, чтобы открыть его интерактивную консоль.", + "lockedAgent": "Удалённое управление отключено" + }, + "search": "Поиск потоков…", + "refresh": "Обновить", + "new": "Новый поток", + "view": "Просмотр", + "system": "Системный", + "loading": "Загрузка потоков…", + "loadError": "Не удалось загрузить потоки.", + "retry": "Повторить", + "empty": "Нет потоков для этого вида.", + "templates": { + "title": "Новый поток", + "subtitle": "Выберите шаблон действия или начните с нуля.", + "loading": "Загрузка шаблонов…", + "loadError": "Не удалось загрузить шаблоны.", + "empty": "Шаблоны отсутствуют.", + "cancel": "Отмена", + "scratch": "Начать с нуля" + }, + "tabs": { + "flows": "Потоки", + "executions": "История выполнений", + "all": "Все", + "active": "Активные", + "inactive": "Неактивные", + "system": "Системные", + "user": "Свои" + }, + "cols": { + "flow": "Поток", + "platform": "Платформа", + "conditions": "Условия", + "commands": "Команды", + "active": "Активен", + "lastRun": "Последний запуск", + "failedRuns_one": "{{count}} неудачный запуск", + "failedRuns_other": "{{count}} неудачных запусков" + }, + "operator": { + "IS": "равно", + "IS_NOT": "не равно", + "CONTAINS": "содержит", + "NOT_CONTAINS": "не содержит", + "EXISTS": "существует", + "NOT_EXISTS": "не существует", + "START_WITH": "начинается с", + "NOT_START_WITH": "не начинается с", + "ENDS_WITH": "заканчивается на", + "NOT_ENDS_WITH": "не заканчивается на", + "IS_ONE_OF": "одно из", + "IS_NOT_ONE_OF": "не одно из" + }, + "toast": { + "created": "Поток создан", + "saved": "Поток сохранён", + "saveError": "Не удалось сохранить поток", + "deleted": "Поток удалён", + "deleteError": "Не удалось удалить поток", + "activateError": "Не удалось изменить состояние потока" + }, + "editor": { + "createTitle": "Новый поток", + "visualTab": "Визуально", + "codeTab": "Код", + "name": "Имя", + "description": "Описание", + "conditions": "Условия", + "conditionsHint": "Поток запускается, когда алерт удовлетворяет ВСЕМ этим условиям.", + "field": "поле", + "value": "значение", + "valueList": "значения через запятую", + "addCondition": "Добавить условие", + "commands": "Команды", + "commandsHint": "Выполняются по порядку на агенте. Используйте $(field.path) для значений алерта и $[variables.NAME] для сохранённых переменных.", + "addCommand": "Добавить команду", + "templatesButton": "Частые команды", + "templates": { + "isolate": "Изолировать от сети", + "shutdown": "Выключить машину", + "killProcess": "Завершить процесс", + "logout": "Завершить сеанс пользователя", + "disableUser": "Отключить пользователя", + "blockIp": "Заблокировать IP", + "restart": "Перезагрузить машину", + "uninstall": "Удалить приложение" + }, + "connector": { + "always": "всегда", + "success": "при успехе", + "failure": "при ошибке" + }, + "agentPlatform": "Платформа агента", + "shell": "Оболочка", + "shellAuto": "авто", + "whereToRun": "Где выполнять", + "run": { + "all": "Все агенты", + "specific": "Один агент", + "except": "Все, кроме", + "allHint": "Выполняется на всех агентах, соответствующих этой платформе." + }, + "selectAgentPlaceholder": "Выберите агента…", + "excludedAgentsHint": "введите имя хоста и нажмите Enter", + "save": "Сохранить", + "delete": "Удалить", + "confirmDelete": "Подтвердить удаление", + "cancel": "Отмена", + "yamlError": "Не удалось применить YAML: {{error}}", + "nameRequired": "Имя обязательно", + "conditionsRequired": "Требуется хотя бы одно условие с полем", + "commandsRequired": "Требуется хотя бы одна команда", + "httpUrlInvalid": "Узел HTTP \"{{id}}\" содержит недопустимый URL — должен быть допустимый http(s) URL.", + "httpBodyInvalid": "Тело узла HTTP \"{{id}}\" не является допустимым JSON: {{error}}", + "incidentNameRequired": "Узлу инцидента \"{{id}}\" требуется имя.", + "mailToRequired": "Узлу электронной почты \"{{id}}\" требуется хотя бы один получатель.", + "mailAddressInvalid": "Узел электронной почты \"{{id}}\" содержит недопустимый адрес {{field}}: {{address}}.", + "mailSubjectRequired": "Узлу электронной почты \"{{id}}\" требуется тема.", + "identityModalTitle": "Свойства потока", + "platformRequired": "Платформа агента обязательна", + "nameLabel": "Название", + "namePlaceholder": "Имя потока", + "descriptionLabel": "Описание", + "descriptionHint": "Что делает этот поток? (необязательно)", + "when": "Когда", + "whenTitle": "Алерт удовлетворяет всем этим условиям", + "on": "На", + "onTitle": "Совпавший агент", + "thenRun": "Тогда выполнить", + "thenTitle": "Эти команды, по порядку", + "selectField": "Выберите поле…", + "selectPlatform": "Выберите платформу…", + "searchAgents": "Поиск агентов…", + "noAgents": "Нет агентов", + "insertInto": "Вставить в команду {{n}}:", + "insertField": "Поле алерта", + "variables": "Переменные", + "canvas": { + "node": "Узел", + "deleteNode": "Удалить узел", + "id": "ID", + "kind": "Тип", + "executor": "Исполнитель", + "commandLabel": "Команда", + "paramsJson": "Параметры (JSON)", + "dragToResize": "Потяните, чтобы изменить размер", + "templatesLabel": "Шаблоны", + "templatesNeedPlatform": "Сначала выберите целевую платформу", + "handlesHint": "Потяните от зелёного разъёма (снизу слева) для on_success и от красного (снизу справа) для on_error. Несколько связей = параллельно. Несколько связей к одному узлу = AND-join.", + "invalidJson": "недопустимый JSON", + "hidePalette": "Скрыть палитру", + "hideInspector": "Скрыть инспектор", + "paletteLabel": "Палитра", + "nodeShort": "Узел", + "showPanel": "Показать {{name}}", + "platform": "Платформа", + "shell": "Оболочка", + "any": "любая", + "auto": "авто", + "runOn": "Запуск на", + "runAutoTitle": "Запускается на хосте, где сработало предупреждение", + "runSpecificTitle": "Закрепить за одним хостом (или шаблоном вида $(alert.foo))", + "runExceptTitle": "Запускается на хосте, где сработало предупреждение, но пропускает указанные в списке", + "runAutoLabel": "источник алерта", + "runSpecificLabel": "один хост", + "runExceptLabel": "все кроме", + "runAutoHint": "Запускается на $(alert.dataSource) — хосте, где сработало предупреждение.", + "pickHost": "выберите хост…", + "orTemplateHint": "Или введите шаблон — $(alert.field) вычисляется при каждом запуске.", + "addExclusion": "добавить исключение", + "searchAgents": "поиск агентов…", + "noAgents": "нет агентов", + "insertField": "Вставить поле", + "alert": "Алерт", + "wholeOutput": "весь вывод (отредактируйте путь)", + "noAncestorsHint": "Пока нет предков обогащения — добавьте узел обогащения выше по цепочке, чтобы его вывод стал доступен здесь.", + "inserts": "вставляет", + "conditionalHint": "Все условия должны совпадать. Совпадение → ветвь успеха (зелёная); несовпадение → ветвь ошибки (красная).", + "http": { + "url": "URL", + "urlInvalid": "Недопустимый http(s) URL.", + "method": "Метод", + "body": "Тело (JSON)", + "bodyInvalid": "Недопустимый JSON", + "headers": "HTTP-заголовки", + "params": "Параметры запроса", + "key": "Ключ", + "value": "Значение", + "addHeader": "Добавить заголовок", + "addParam": "Добавить параметр" + }, + "incident": { + "name": "Название инцидента", + "namePlaceholder": "Напр. Подозрительный вход на $(alert.dataSource)", + "description": "Описание", + "descriptionPlaceholder": "Дополнительный контекст для отвечающих. Шаблоны вроде $(alert.name) подставляются." + }, + "llm": { + "prompt": "Промпт", + "hint": "Модель всегда отвечает одним JSON-объектом со свойством \"result\"; backend гарантирует этот формат даже если модель отклоняется. Дочерние узлы обращаются к нему через $({{nodeId}}.result) или конкретные поля." + }, + "mail": { + "to": "Кому (через запятую)", + "cc": "Копия (через запятую, опционально)", + "addressInvalid": "Недопустимый адрес электронной почты: {{address}}", + "subject": "Тема", + "subjectPlaceholder": "Напр. Тревога на $(alert.dataSource)", + "body": "Текст", + "bodyPlaceholder": "Содержимое сообщения. Шаблоны вроде $(alert.name) подставляются." + }, + "notify": { + "level": "Level", + "message": "Message", + "messagePlaceholder": "Notification text. Templates like $(alert.name) are interpolated." + } } - }, - "intro": { - "title": "Принцип работы", - "body": "UTMStack считывает активность аудита непосредственно из Google Cloud через Pub/Sub. Маршрутизатор журналов направляет журналы проекта в тему Pub/Sub; UTMStack запускает внутренний сборщик, который читает Pull-подписку этой темы с помощью ключа сервисного аккаунта. В вашем GCP-проекте ничего не устанавливается.", - "diagram": { - "source": "Cloud Logging", - "edge1": "Logs Router", - "pubsub": "Pub/Sub", - "pubsubSub": "тема + подписка", - "edge2": "получает", - "utmstackSub": "оповещения и корреляция" - }, - "note": "В GCP агенты не запускаются — UTMStack получает сообщения из подписки Pub/Sub с помощью JSON-ключа сервисного аккаунта, который вы укажете ниже." - }, - "credentials": { - "title": "Конфигурация Pub/Sub", - "body": "Используйте собранные выше значения для настройки UTMStack. Вы можете отслеживать несколько проектов, сохранив дополнительные конфигурации.", - "mapping": { - "intro": "Справочник полей", - "projectId": "Project ID — GCP-проект, содержащий вашу тему, подписку и маршрутизатор журналов", - "subscription": "Имя подписки — Pull-подписка, созданная на шаге 2", - "jsonKey": "JSON-ключ сервисного аккаунта — файл, загруженный на шаге 8" + }, + "executions": { + "search": "Поиск по ID алерта…", + "all": "Все", + "loading": "Загрузка выполнений…", + "loadError": "Не удалось загрузить выполнения.", + "retry": "Повторить", + "empty": "Пока нет выполнений.", + "cols": { + "status": "Статус", + "flow": "Поток", + "command": "Команда / Действие", + "agent": "Агент", + "date": "Дата", + "retries": "Попытки", + "node": "Узел" + }, + "manual": "Интерактивная консоль", + "filters": { + "source": "Source", + "allSources": "All sources" } - } }, - "azure": { - "sections": { - "sharedAccessPolicy": { - "title": "2 · Добавьте политику общего доступа", - "body": "Откройте Event Hub → Политики общего доступа и создайте новую политику только с разрешением Listen." - }, - "connectionString": { - "title": "3 · Скопируйте основную строку подключения", - "body": "Откройте политику и скопируйте основную строку подключения. Она выглядит так: Endpoint=sb://...;SharedAccessKeyName=...;SharedAccessKey=..." - }, - "consumerGroup": { - "title": "4 · Создайте отдельную consumer group", - "body": "Откройте Event Hub → Consumer groups и создайте новую для UTMStack. Не используйте $Default — выделите UTMStack собственную группу, чтобы контрольные точки не пересекались с другими потребителями.", - "warn": "Создайте группу потребителей специально для UTMStack. Не используйте $Default или другие уже используемые группы — совместное использование группы потребителей несвязанными потребителями может привести к непредвиденному поведению и потере событий. Все экземпляры UTMStack должны использовать одну группу потребителей для совместной обработки событий." - }, - "storageContainer": { - "title": "6 · Создайте контейнер в учётной записи хранения", - "body": "В учётной записи хранения → Контейнеры создайте новый контейнер. Запишите имя контейнера и строку подключения учётной записи (Ключи доступа → Строка подключения)." - }, - "eventGrid": { - "title": "7 · Зарегистрируйте поставщик ресурсов Event Grid", - "body": "В Подписки → Поставщики ресурсов зарегистрируйте Microsoft.EventGrid, если ещё нет. Это позволит Azure пересылать события уровня подписки в ваш Event Hub." - }, - "createEventHub": { - "title": "Создать Event Hub", - "body": "На портале Azure создайте пространство имён Event Hubs и Event Hub внутри него. UTMStack будет считывать события из этого концентратора.", - "docLabel": "Краткое руководство: создание концентратора событий с помощью портала Azure" - }, - "createStorageAccount": { - "title": "Создать Storage Account", - "body": "UTMStack требуется Storage Account для сохранения контрольных точек позиции чтения. Создайте его в том же регионе, что и Event Hub.", - "docLabel": "Краткое руководство: создание учётной записи хранилища" - }, - "storageConnection": { - "title": "Скопировать строку подключения Storage Account", - "body": "Получите строку подключения Storage Account с ключом в разделе: All services → Storage accounts → ваша учётная запись → Access keys. UTMStack использует её для хранения контрольных точек Event Hub." - }, - "createEventSubscription": { - "title": "Создать подписку на события", - "body": "На панели Events подписки создайте новое событие, нажав Events → Event Subscription." - }, - "configureEventSubscription": { - "title": "Направить подписку на события в Event Hub", - "body": "Настройте подписку на события для отправки журналов в Event Hub, созданный на шаге 1." - } - }, - "fields": { - "eventHubConnection": { - "label": "Строка подключения Event Hub" - }, - "consumerGroup": { - "label": "Consumer group" - }, - "storageContainer": { - "label": "Имя контейнера хранения" - }, - "storageConnection": { - "label": "Строка подключения учётной записи хранения" - } - }, - "intro": { - "title": "Принцип работы", - "body": "UTMStack считывает активность аудита непосредственно из Azure Event Hub. Вы настраиваете подписку Azure для потоковой передачи событий в Event Hub; UTMStack запускает внутренний сборщик, который читает этот концентратор и сохраняет контрольные точки в Storage Account. В вашем тенанте Azure ничего не устанавливается.", - "diagram": { - "source": "события подписки", - "edge1": "передаёт в", - "eventHub": "Event Hub", - "eventHubSub": "поток событий", - "edge2": "получает", - "utmstackSub": "оповещения и корреляция" - }, - "note": "В Azure агенты не запускаются — UTMStack получает события из Event Hub с помощью строк подключения, которые вы укажете ниже." - }, - "sampleLabel": "Пример строки подключения:", - "credentials": { - "title": "Конфигурация Event Hub", - "body": "Используйте данные, собранные на предыдущих шагах, для настройки UTMStack. Вы можете добавить несколько Event Hub, сохранив дополнительные конфигурации.", - "mapping": { - "intro": "Справочник полей", - "eventHubConnection": "Строка подключения Event Hub — значение, полученное на шаге 3", - "consumerGroup": "Группа потребителей — значение, полученное на шаге 4", - "storageContainer": "Имя контейнера хранилища — значение, полученное на шаге 6", - "storageConnection": "Строка подключения учётной записи хранилища — значение, полученное на шаге 7" - } - } + "executionStatus": { + "WAITING": "В ожидании", + "PENDING": "В очереди", + "EXECUTING": "Выполняется", + "EXECUTED": "Выполнено", + "FAILED": "Ошибка", + "DEAD": "Недостижимо" }, - "aws": { - "fields": { - "accessKeyId": { - "label": "ID ключа доступа AWS" - }, - "secretAccessKey": { - "label": "Секретный ключ доступа AWS" - }, - "region": { - "label": "Регион AWS по умолчанию" - }, - "logGroupName": { - "label": "Имя log group" - } - }, - "intro": { - "title": "Принцип работы", - "body": "UTMStack считывает активность аудита непосредственно из AWS CloudWatch Logs. CloudTrail фиксирует вызовы API и события управления в вашем аккаунте AWS, пересылает их в группу журналов CloudWatch, а UTMStack опрашивает эту группу для приёма и корреляции событий.", - "diagram": { - "source": "события API", - "edge1": "CloudTrail", - "cloudwatchSub": "группы журналов", - "edge2": "опрашивает", - "utmstackSub": "оповещения и корреляция" - }, - "note": "На AWS агенты не устанавливаются — UTMStack получает события журналов с помощью учётных данных IAM с правами только на чтение, которые вы укажете ниже." - }, - "iamSection": "Настроить пользователя IAM", - "iam": { - "dashboard": { - "title": "Открыть панель управления IAM", - "body": "Откройте консоль AWS, перейдите на панель управления IAM и выберите Users." - }, - "addUser": { - "title": "Добавить пользователя", - "body": "Нажмите Add user, введите понятное имя пользователя и перейдите к следующему шагу." - }, - "attachPolicy": { - "title": "Прикрепить политику только для чтения", - "body": "В разделе Permissions прикрепите необходимую политику. Выберите CloudWatchLogsReadOnlyAccess для доступа только для чтения к CloudWatch." - }, - "createUser": { - "title": "Создать пользователя", - "body": "Проверьте конфигурацию и нажмите Create user для создания аккаунта." - }, - "openUser": { - "title": "Открыть нового пользователя", - "body": "Откройте только что созданного пользователя, щёлкнув по его имени, чтобы просмотреть сведения и управлять учётными данными." - }, - "securityTab": { - "title": "Перейти в раздел Security credentials", - "body": "Выберите вкладку Security credentials для создания ключей программного доступа." - }, - "createKey": { - "title": "Создать ключ доступа", - "body": "Нажмите Create access key и выберите вариант для приложения, работающего вне AWS (программный доступ)." - }, - "confirmKey": { - "title": "Подтвердить создание", - "body": "Подтвердите создание ключа доступа. AWS сгенерирует Access Key ID и Secret Access Key." - }, - "downloadKey": { - "title": "Сохранить учётные данные", - "body": "Загрузите файл с учётными данными или скопируйте Access Key ID и Secret Access Key в надёжное место — Secret Access Key отображается только один раз." - } - }, - "credentials": { - "title": "Ввести учётные данные", - "body": "Вставьте Access Key ID и Secret Access Key, полученные на предыдущих шагах. UTMStack проверяет учётные данные в AWS перед сохранением." - }, - "cloudwatchSection": "Настроить AWS CloudWatch", - "cloudwatch": { - "createGroup": { - "title": "Создать группу журналов CloudWatch", - "body": "Откройте консоль CloudWatch, выберите Log management и нажмите Create log group." - }, - "nameGroup": { - "title": "Задать имя группы журналов и срок хранения", - "body": "Введите имя группы журналов utmstack и установите срок хранения 1 day. Нажмите Create log group." - }, - "openTrail": { - "title": "Открыть CloudTrail и создать трейл", - "body": "В консоли CloudTrail нажмите Create trail, чтобы начать настройку нового трейла." - }, - "configureTrail": { - "title": "Настроить доставку, проверку и интеграцию с CloudWatch", - "body": "В форме создания CloudTrail задайте следующие параметры:", - "items": [ - "Trail name and scope: введите понятное имя; включите Apply trail to all accounts in my organization, если требуется сбор данных по всей организации.", - "S3 destination: выберите Create new S3 bucket (или укажите существующий бакет) для доставки необработанных журналов.", - "Encryption: включите Log file SSE-KMS и выберите подходящий KMS-ключ.", - "Log file validation: включите для обеспечения целостности доставляемых журналов (рекомендуется).", - "CloudWatch Logs: включите доставку в CloudWatch, выберите Use existing log group и введите точное имя utmstack.", - "IAM role: укажите или создайте роль, которую CloudTrail будет использовать для записи в S3 и публикации в CloudWatch." - ] - }, - "eventTypes": { - "title": "Выбрать типы событий", - "body": "Включите категории событий, необходимые для мониторинга и аудита.", - "management": { - "label": "1 · События управления", - "body": "Включите Management events и выберите All, чтобы записывать всю активность API, управляющую ресурсами AWS (создание, обновление, удаление)." - }, - "data": { - "label": "2 · События данных", - "body": "Добавьте Data event. Выберите S3 и укажите Log all events, чтобы фиксировать операции на уровне объектов, такие как GetObject и PutObject." - }, - "network": { - "label": "3 · События сетевой активности", - "body": "В разделе Network Activities добавьте хотя бы одну службу (например, ec2.amazonaws.com) и включите Log all events." - } - }, - "review": { - "title": "Проверьте и создайте трейл", - "body": "На экране Configure event aggregation примите значения по умолчанию (или измените при необходимости). Проверьте все настройки и нажмите Create trail." - } - } - }, - "crowdstrike": { - "intro": { - "title": "Как это работает", - "body": "UTMStack считывает обнаружения и активность аудита напрямую из CrowdStrike Falcon Event Streams API. Вы создаёте API-клиент в Falcon с областью Event Streams; UTMStack запускает внутренний пуллер, который получает события с использованием этих учётных данных. На ваших конечных точках или в Falcon ничего не устанавливается.", - "diagram": { - "source": "обнаружения и события", - "edge1": "Event Streams API", - "api": "Falcon API", - "apiSub": "поток событий", - "edge2": "получает", - "utmstackSub": "оповещения и корреляция" - }, - "note": "UTMStack не устанавливает агентов — он получает события из Falcon, используя предоставленные вами ниже учётные данные API-клиента (только чтение)." - }, - "sections": { - "apiClients": { - "title": "Откройте API Clients and Keys", - "body": "В консоли Falcon откройте меню (значок гамбургера, в верхнем левом углу) и перейдите в Support and resources → API Clients and Keys." - }, - "createClient": { - "title": "Создайте новый API-клиент", - "body": "Нажмите Create API Client, чтобы начать создание нового клиента." - }, - "scopes": { - "title": "Задайте имя клиента и назначьте область Event Streams", - "body": "Присвойте клиенту понятное имя (UTMStack использует его для идентификации источника событий) и выберите области API, необходимые для Event Streams. Нажмите Create для генерации учётных данных." - }, - "recordCredentials": { - "title": "Сохраните учётные данные", - "body": "Скопируйте Client ID, Client Secret и Base URL для вашего региона CrowdStrike. Секрет отображается только один раз — сохраните его в надёжном месте. Все три значения нужно будет вставить в форму ниже." - } - }, - "credentials": { - "title": "Конфигурация API-клиента", - "body": "Используйте учётные данные из шагов выше для настройки UTMStack. Вы можете добавить несколько клиентов CrowdStrike, сохранив дополнительные конфигурации.", - "mapping": { - "intro": "Описание полей", - "appName": "Имя приложения — понятное имя клиента из шага 3 (идентифицирует источник событий)", - "clientId": "Client ID — значение, сохранённое на шаге 4", - "clientSecret": "Client Secret — значение, сохранённое на шаге 4 (отображается только один раз)", - "cloudRegionUrl": "Base URL — конечная точка вашего региона, например https://api.crowdstrike.com (us-1), https://api.us-2.crowdstrike.com (us-2), https://api.eu-1.crowdstrike.com (eu-1)" - } - }, - "fields": { - "appName": { - "label": "Имя приложения" - }, - "clientId": { - "label": "Client ID" - }, - "clientSecret": { - "label": "Client Secret" - }, - "cloudRegionUrl": { - "label": "Base URL (облачный регион)" - } - } - } - }, - "custom": { - "whenTitle": "Когда это использовать", - "whenBody": "Когда ваш источник отсутствует в каталоге. Перенаправьте произвольный syslog или JSON в UTMStack и определите парсер для нормализации полей.", - "endpointsTitle": "Конечные точки", - "syslogUdp": "Syslog (UDP)", - "syslogTls": "Syslog (TLS)", - "httpJson": "HTTP / JSON", - "payloadTitle": "Пример payload JSON", - "parserTitle": "Определить парсер", - "parserBody": "Входящие события сохраняются под типом данных {{dataType}}. Добавьте фильтр разбора, чтобы необработанные данные сопоставлялись со структурированными полями, затем создавайте на их основе правила оповещений.", - "openEditor": "Открыть редактор парсера", - "powershellLabel": "PowerShell (запустить от имени администратора)", - "linuxLabel": "Linux — bash", - "macosLabel": "macOS — bash", - "exampleLabel": "Пример целевого syslog на {{name}}:", - "intro": { - "title": "Как это работает", - "body": "Пользовательская интеграция принимает журналы из любого источника, не охваченного встроенными модулями. Вы устанавливаете UTMStack Collector, регистрируете слушатель для ваших данных с выбранным протоколом и указываете источник на него.", - "note": "Выберите протокол, который может использовать ваш источник (syslog UDP/TCP/TLS или HTTP/HTTPS для JSON) ниже — Collector автоматически создаст тип данных." - }, - "diagram": { - "source": "Ваш источник", - "sourceSub": "любое приложение или устройство", - "forwarder": "Collector", - "ingests": "принимает", - "utmstackSub": "оповещения и корреляция" - }, - "choose": { - "title": "Выберите протокол и порт", - "body": "Выберите способ отправки данных источником и порт, на котором должен слушать Collector, затем выполните команду активации на хосте Collector.", - "portLabel": "Порт прослушивания", - "tlsFirst": "Сначала загрузите ваш TLS-сертификат и ключ на Collector:", - "enableLabel": "Затем включите интеграцию:", - "authNote": "Для включения аутентификации добавьте --auth bearer (токен) или --auth hmac — Collector выведет токен для использования в заголовке Authorization." - }, - "send": { - "title": "Направьте ваш источник на Collector", - "bodyNetwork": "Настройте ваш источник для отправки syslog {{proto}} на {{host}}:{{port}}. На большинстве устройств для этого есть параметр удалённого syslog или пересылки журналов.", - "bodyHttp": "Отправляйте события в формате JSON через HTTP POST на {{endpoint}}. Тело каждого запроса — одно событие JSON:", - "httpBindNote": "По умолчанию слушатель HTTP/HTTPS привязывается к 127.0.0.1 (хосту Collector), поэтому отправляйте запросы из приложения, работающего на этом хосте, или используйте обратный прокси. Для удалённых источников используйте syslog (UDP/TCP/TLS)." - }, - "manualCommand": { - "title": "Optional — Enable via the command line instead", - "intro": "Prefer the terminal? SSH into the Collector host and run the command below — it matches whatever protocol and port you have selected above." + "nonExecutionCause": { + "AGENT_OFFLINE": "Агент офлайн", + "AGENT_NOT_FOUND": "Агент не найден", + "UNKNOWN": "Неизвестно" + }, + "kpi": { + "flows": "Всего потоков", + "active": "Активные", + "runs24h": "Выполнения (24 ч)", + "failed24h": "Неудачные (24 ч)" + }, + "neverRun": "никогда", + "create": { + "title": "Новый поток", + "modeManual": "Создать вручную", + "modeAi": "С помощью ИИ", + "aiLocked": "Включите SOC-AI и настройте его, чтобы использовать это.", + "name": "Имя потока", + "namePlaceholder": "напр. Заблокировать IP при повторных сбоях", + "aiDescriptionLabel": "Что должен делать этот поток?", + "aiDescriptionPlaceholder": "напр. При критическом оповещении найти исходный IP в разведданных и заблокировать его на файрволе", + "aiCreate": "Создать с ИИ", + "manualContinue": "Продолжить" + }, + "executionOrigin": { + "FLOW": "Flow", + "MANUAL": "Manual" } - }, - "remoteEnable": { - "title": "Включить эту интеграцию удалённо", - "body": "Выберите Collector, протокол и порт, затем включите интеграцию — SSH не требуется.", - "noPermission": "У вас нет прав на управление удалёнными интеграциями. Попросите администратора предоставить разрешение integrations.write.", - "loadingCollectors": "Загрузка Collectors…", - "noCollectors": "Ни один Collector ещё не зарегистрирован. Установите один выше, чтобы включить интеграции удалённо.", - "forwarderOffline": "Этот Collector находится в режиме офлайн и сейчас не может получать изменения конфигурации.", - "legendOnline": "{{count}} в сети", - "legendOffline": "{{count}} офлайн", - "legendTotal": "{{count}} всего", - "forwarderLabel": "Collector", - "protoLabel": "Протокол", - "portLabel": "Порт", - "currentStateLoading": "Проверка текущей конфигурации…", - "currentlyEnabled": "Сейчас: включено · {{proto}} · порт {{port}}", - "currentlyDisabled": "Сейчас: отключено · {{proto}} · порт {{port}}", - "authLabel": "Аутентификация", - "authNone": "Нет", - "authBearer": "Bearer-токен", - "authHmac": "HMAC-подпись", - "pathLabel": "Путь", - "signatureHeaderLabel": "Заголовок подписи", - "certTitle": "TLS-сертификат", - "certLoading": "Проверка статуса сертификата…", - "certLoaded": "Действительный сертификат уже загружен на этот Collector.", - "certMissing": "Сертификат ещё не загружен — загрузите один, чтобы включить этот протокол.", - "certInvalid": "Загруженный сертификат недействителен: {{error}}", - "certPemLabel": "Сертификат", - "keyPemLabel": "Закрытый ключ", - "caPemLabel": "Сертификат ЦА", - "uploadCertsButton": "Загрузить сертификат", - "certUploadSuccess": "Сертификат загружен.", - "certUploadError": "Не удалось загрузить сертификат.", - "certReadError": "Не удалось прочитать выбранный файл(ы).", - "enableButton": "Включить интеграцию", - "disableButton": "Отключить интеграцию", - "enableSuccess": "Интеграция включена.", - "disableSuccess": "Интеграция отключена.", - "enableError": "Не удалось обновить интеграцию.", - "secretWarning": "Сохраните этот токен в безопасном месте — он больше не будет показан.", - "sendToInstance": "Отправить на инстанс", - "enterpriseFeature": "Это функция Enterprise.", - "addCollector": "Добавить Collector", - "addApiKey": "Добавить API-ключ", - "apiKeyLabel": "API-ключ", - "apiKeyHint": "Сначала вам понадобится API-ключ.", - "apiKeyPlaceholder": "Выберите API-ключ", - "apiKeyAddNew": "Добавить API-ключ…", - "apiKeyNone": "Нет ни одного API-ключа", - "forwarderNoRemoteControl": "Этот форвардер установлен с отключённым удалённым управлением. Он игнорирует конфигурацию, отправленную отсюда; изменить это можно только на самой машине." - } - }, - "codeBlock": { - "copy": "Копировать", - "copied": "Скопировано" - }, - "createDrawer": { - "title": "Новая пользовательская интеграция", - "moduleName": "Имя модуля", - "moduleNameHint": "Уникальный идентификатор. Без пробелов.", - "moduleNamePlaceholder": "moya-custom-app", - "prettyName": "Отображаемое имя", - "prettyNamePlaceholder": "Moya Custom App", - "dataType": "Тип данных", - "dataTypePlaceholder": "Уникальный идентификатор для этого типа данных", - "icon": "Значок", - "iconHint": "PNG, SVG, JPEG, GIF или WEBP. Максимум 3 МБ. Используется как логотип интеграции.", - "iconPreview": "Предпросмотр значка", - "dataTypeExists": "Этот тип данных уже существует", - "invalidFileType": "Значок должен быть действительным файлом изображения (PNG, JPEG, SVG, GIF, WEBP)", - "fileTooLarge": "Значок не должен превышать 3 МБ", - "fileReadError": "Ошибка при чтении файла", - "cancel": "Отмена", - "create": "Создать интеграцию", - "creating": "Создание…", - "editTitle": "Редактировать интеграцию", - "save": "Сохранить", - "saving": "Сохранение…", - "currentIcon": "Текущий значок — загрузите файл для замены", - "name": "Название интеграции", - "namePlaceholder": "например, Acme Firewall", - "description": "Описание", - "descriptionPlaceholder": "Что принимает эта интеграция и зачем (необязательно)", - "identifierHint": "Сохраняется как “{{id}}” (производное от имени)", - "nameTaken": "Это название интеграции нельзя использовать — интеграция с таким идентификатором уже существует.", - "removeIcon": "Удалить значок", - "defaultIconNote": "Значок по умолчанию — загрузите файл, чтобы использовать собственный." - }, - "toast": { - "created": "Интеграция создана", - "updated": "Интеграция обновлена", - "updateError": "Не удалось обновить интеграцию" - }, - "delete": { - "title": "Удалить интеграцию", - "confirm": "Удалить эту интеграцию?", - "yes": "Удалить", - "no": "Отмена", - "deleted": "Интеграция удалена", - "error": "Не удалось удалить интеграцию" - }, - "modules": { - "WINDOWS_AGENT": "Сбор системной, защитной активности и журналов событий Windows через лёгкий агент UTMStack, установленный на каждом хосте.", - "LINUX_AGENT": "Сбор системных журналов, журналов аутентификации и аудита Linux через лёгкий агент UTMStack, установленный на каждом хосте.", - "MACOS": "Сбор системных журналов и журналов безопасности macOS с конечных точек Apple Mac через лёгкий агент UTMStack.", - "VMWARE": "Приём syslog гипервизора VMware ESXi для мониторинга активности и событий хостов виртуализации в UTMStack.", - "NETFLOW": "Приём записей NetFlow от маршрутизаторов и коммутаторов для мониторинга сетевого трафика и обнаружения аномалий.", - "AWS_IAM_USER": "Приём активности учётных записей AWS и вызовов API через CloudTrail и CloudWatch для аудита использования облака, доступа и изменений.", - "AZURE": "Приём журналов платформы и активности Microsoft Azure для мониторинга облачных нагрузок, удостоверений и изменений ресурсов.", - "O365": "Приём журналов аудита Microsoft 365 по Exchange, Teams, SharePoint и OneDrive для мониторинга активности пользователей и администраторов.", - "O365_GRAPH": "Захват событий безопасности Microsoft Graph — оповещения, инциденты, аудит каталога, sign-in, обнаружения рисков и журналы аудита Purview — для мониторинга идентификации и угроз в вашем tenant.", - "GCP": "Приём журналов аудита и активности Google Cloud Platform для мониторинга вычислений, хранилища и удостоверений в проектах.", - "KASPERSKY": "Приём обнаружений Kaspersky Security Center и телеметрии конечных точек для корреляции активности вредоносного ПО в сети.", - "ESET": "Приём обнаружений конечных точек ESET PROTECT и телеметрии для корреляции многоуровневой защиты от вредоносного ПО.", - "BITDEFENDER": "Приём обнаружений Bitdefender GravityZone и телеметрии конечных точек для корреляции угроз на корпоративных устройствах.", - "SENTINEL_ONE": "Приём обнаружений конечных точек SentinelOne и поведенческой телеметрии для масштабной корреляции и расследования угроз.", - "SOPHOS": "Приём обнаружений Sophos Central по конечным точкам, серверам, межсетевым экранам и электронной почте для корреляции угроз в одном месте.", - "CROWDSTRIKE": "Приём обнаружений конечных точек и рабочих нагрузок CrowdStrike Falcon для корреляции активности облачных угроз в UTMStack.", - "CISCO": "Приём журналов трафика, VPN и угроз межсетевого экрана Cisco ASA для мониторинга защиты периметра и доступа в UTMStack.", - "MERAKI": "Приём syslog межсетевого экрана и устройств безопасности Cisco Meraki для мониторинга управляемого из облака сетевого трафика и угроз.", - "FIRE_POWER": "Приём журналов Cisco Firepower NGFW и IPS для мониторинга попыток вторжения и угроз на периметре.", - "CISCO_SWITCH": "Приём syslog и телеметрии коммутаторов Cisco для мониторинга производительности сети, изменений конфигурации и безопасности.", - "FORTIGATE": "Приём журналов трафика и угроз Fortinet FortiGate NGFW для мониторинга защиты периметра и сетевой активности.", - "FORTIWEB": "Приём журналов WAF Fortinet FortiWeb для мониторинга атак на веб-приложения и защиты открытых сервисов и API.", - "SOPHOS_XG": "Приём журналов межсетевого экрана Sophos XG, включающих веб-фильтрацию, IPS и VPN, для мониторинга сетевого трафика и угроз.", - "PALO_ALTO": "Приём журналов трафика и угроз Palo Alto Networks NGFW для мониторинга использования приложений и защиты периметра.", - "SONIC_WALL": "Приём журналов трафика и угроз SonicWall NGFW для мониторинга защиты периметра и сетевой активности в UTMStack.", - "PFSENSE": "Приём журналов межсетевого экрана и маршрутизатора pfSense с унифицированным управлением угрозами для мониторинга сетевого трафика и угроз.", - "MIKROTIK": "Приём журналов межсетевого экрана, маршрутизации и беспроводной сети MikroTik RouterOS для мониторинга сетевой активности и конфигурации.", - "AIX": "Сбор системных журналов, журналов безопасности и аудита IBM AIX Unix для мониторинга активности на платформах IBM Power в UTMStack.", - "AS_400": "Сбор системных журналов и журналов аудита IBM AS/400 (IBM i) для мониторинга активности пользователей на платформах OS/400.", - "ORACLE": "Приём журналов аудита Oracle Database для мониторинга запросов, доступа и привилегированных операций в базах данных.", - "SURICATA": "Приём оповещений Suricata IDS/IPS и сетевых событий для обнаружения вторжений и вредоносного трафика в сети.", - "DECEPTIVE_BYTES": "Приём оповещений Deceptive Bytes от платформы активного обмана конечных точек для раннего выявления активности злоумышленников.", - "GITHUB": "Приём журналов аудита GitHub для мониторинга доступа к репозиториям, изменений кода и активности организации в целях безопасности исходного кода.", - "UTMSTACK": "Приём телеметрии UTMStack SIEM и XDR для мониторинга работоспособности платформы, внутренней активности и событий самоаудита.", - "NGINX": { - "name": "Nginx", - "description": "Приём журналов доступа и ошибок Nginx для мониторинга активности веб-сервера, трафика обратного прокси и запросов клиентов." - }, - "APACHE": { - "name": "Apache", - "description": "Приём журналов доступа и ошибок Apache HTTPD для мониторинга активности веб-сервера и запросов клиентов." - }, - "APACHE2": { - "name": "Apache2", - "description": "Приём журналов веб-сервера Apache2 (HTTPD) для мониторинга обработки запросов, ошибок и доступа на хостах Linux." - }, - "IIS": { - "name": "IIS", - "description": "Приём активности доступа и журналов Internet Information Services (IIS) для мониторинга веб-обслуживания Windows." - }, - "MYSQL": { - "name": "MySQL", - "description": "Приём активности журналов MySQL для мониторинга запросов, аутентификации и доступа к хранилищу данных." - }, - "POSTGRESQL": { - "name": "PostgreSQL", - "description": "Приём журналов PostgreSQL для мониторинга запросов, доступа и активности в ваших хранилищах данных." - }, - "MONGODB": { - "name": "MongoDB", - "description": "Приём активности журналов MongoDB для мониторинга доступа к документной базе данных, запросов и поведения приложения." - }, - "REDIS": { - "name": "Redis", - "description": "Приём активности журналов и телеметрии Redis для мониторинга использования хранилища данных в памяти и нагрузок в реальном времени." - }, - "ELASTICSEARCH": { - "name": "Elasticsearch", - "description": "Приём журналов Elasticsearch для мониторинга поискового и аналитического движка и его прикладных нагрузок." - }, - "LOGSTASH": { - "name": "Logstash", - "description": "Приём журналов конвейеров Logstash для мониторинга конвейера обработки данных и преобразования событий." - }, - "KIBANA": { - "name": "Kibana", - "description": "Приём журналов Kibana для мониторинга уровня визуализации и исследования данных и его использования." - }, - "KAFKA": { - "name": "Apache Kafka", - "description": "Приём журналов Apache Kafka для мониторинга конвейеров потоковой передачи в реальном времени, брокеров и потока сообщений." - }, - "NATS": { - "name": "NATS", - "description": "Приём журналов обмена сообщениями NATS для мониторинга шины сообщений, подключённости и доставки событий." - }, - "HAPROXY": { - "name": "HAProxy", - "description": "Приём журналов HAProxy для мониторинга балансировки нагрузки, прокси-трафика и доступности сети." - }, - "TRAEFIK": { - "name": "Traefik", - "description": "Приём журналов Traefik для мониторинга маршрутизации, балансировки нагрузки и прокси-трафика между нагрузками." - }, - "OSQUERY": { - "name": "osquery", - "description": "Приём журналов OsQuery для мониторинга состояния конечных точек, запросов и инвентаризации системы через SQL-подобные запросы." - }, - "SYSLOG": { - "name": "Syslog", - "description": "Отправляйте syslog (RFC 5424/3164) с любого устройства или приложения на конечную точку коллектора для централизованного приёма журналов." - }, - "JSON": { - "name": "JSON Input", - "description": "Отправляйте данные журналов в формате JSON на конечную точку приёма для структурированного сбора событий из приложений и сценариев." - }, - "WINDOWS_SQL_SERVER": { - "name": "SQL Server Event Logs", - "description": "Collect Microsoft SQL Server audit and event records through the Windows Event Log and UTMStack agent." - }, - "WINDOWS_FILE_AUDITING": { - "name": "Windows File Access Auditing", - "description": "Collect Windows file access audit events through the Windows Event Log and UTMStack agent." - }, - "ELASTICsearch": { - "name": "ELASTICsearch", - "description": "Ingesta los registros de Elasticsearch para monitorear el motor de búsqueda y análisis y sus cargas de trabajo de aplicación." - } - }, - "edit": { - "title": "Редактировать интеграцию" - }, - "allCategories": "Все категории", - "customOnly": "Пользовательские" - }, - "datasources": { - "title": "Источники данных", - "total": "всего {{count}}", - "subtitle": "Агенты, интеграции и прямые источники, поставляющие события. Статус определяется по времени последнего появления источника.", - "connectSource": "Подключить источник", - "loading": "Загрузка источников данных…", - "loadFailed": "Не удалось загрузить источники данных.", - "retry": "Повторить", - "none": "Нет источников по этому фильтру.", - "ingestion": { - "title": "Поступление", - "received": "событий получено", - "none": "Нет поступлений за последние 24 часа.", - "ago24h": "24ч назад", - "now": "сейчас" - }, - "usage": { - "title": "Источники данных", - "ofUnlimited": "из неограниченного", - "ofLimit": "из {{limit}}", - "overLimit": "Превышен лицензионный лимит — данные сверх лимита под угрозой.", - "configured": "настроено" - }, - "tabs": { - "all": "Все", - "agent": "Агенты", - "puller": "Интеграции", - "direct": "Прямые", - "offline": "Офлайн" - }, - "toolbar": { - "searchPlaceholder": "Поиск по имени…", - "list": "Список", - "cards": "Карточки", - "refresh": "Обновить" }, - "labels": { - "filteredBy": "Фильтр по label", - "add": "Добавить label…", - "addFirst": "Добавить label…", - "hint": "Введите label и нажмите Enter, чтобы добавить. Изменения сохраняются автоматически." - }, - "status": { - "live": "Активен", - "idle": "Неактивен", - "offline": "Офлайн" - }, - "kind": { - "agent": "Агент", - "puller": "Интеграция", - "direct": "Прямой" - }, - "cols": { - "source": "Источник", - "type": "Тип", - "status": "Статус", - "events24h": "События 24ч", - "lastSeen": "Последний раз" - }, - "time": { - "justNow": "только что", - "minutesAgo": "{{count}} мин назад", - "hoursAgo": "{{count}} ч назад", - "daysAgo": "{{count}} дн назад" - }, - "drawer": { - "loading": "Загрузка…", - "loadFailed": "Не удалось загрузить источник данных.", - "statsIdentity": "Статистика и идентификация", - "metadata": "Метаданные", - "labelsSection": "Labels", - "dangerZone": "Опасная зона", - "rows": { - "events24h": "События 24ч", - "lastSeen": "Последний раз", - "discovered": "Обнаружен", - "kind": "Тип источника", - "dataType": "Тип данных", - "ip": "IP", - "id": "ID" - }, - "dangerText": "Удаление убирает источник из реестра. Исторические события остаются доступны в Log Explorer; если источник продолжит присылать данные, он будет обнаружен заново.", - "delete": "Удалить источник", - "confirmDelete": "Подтвердить удаление", - "cancel": "Отмена", - "viewLogs": "Просмотр журналов", - "trend": "Тренд приёма данных", - "noTrend": "В этом окне события не получены", - "logGap": "Последнее событие {{since}} — возможен пропуск журналов" - }, - "toast": { - "labelsUpdated": "Labels обновлены", - "labelsFailed": "Не удалось обновить labels", - "deleted": "Источник удалён", - "deleteFailed": "Не удалось удалить" - }, - "sensitivity": { - "section": "Чувствительность актива", - "hint": "Бизнес-критичность (CIA, 0–3) этого актива. Алерты по его хосту/IP взвешиваются этими значениями.", - "saved": "Чувствительность обновлена", - "failed": "Не удалось обновить чувствительность", - "save": "Сохранить", - "confidentiality": "Конфиденциальность", - "integrity": "Целостность", - "availability": "Доступность", - "levels": { - "0": "Нет", - "1": "Низкая", - "2": "Средняя", - "3": "Высокая" - } - }, - "limitBanner": { - "title": "Превышен лимит источников данных.", - "message": "У вас {{count}} источников данных, но ваша лицензия покрывает {{limit}}. Журналы из источников сверх лимита отбрасываются.", - "cta": "Управление лицензией", - "dismiss": "Закрыть" + "compliance": { + "title": "Compliance", + "subtitle": "Оцените соответствие фреймворкам безопасности — какие контроли выполнены, а какие нет.", + "comingSoon": "Скоро.", + "tabs": { + "frameworks": "Фреймворки", + "schedule": "Расписание", + "controls": "Контроли" + }, + "search": "Поиск фреймворков…", + "refresh": "Refresh", + "loading": "Загрузка фреймворков…", + "loadError": "Could not load reports", + "retry": "Повторить", + "empty": "Нет подходящих фреймворков.", + "notEvaluated": "Не оценён", + "controlsCount": "Контролей: {{n}}", + "enabledLabel": "Включён", + "runReport": "Запустить отчёт", + "backToFrameworks": "К фреймворкам", + "statusAuto": "Авто (оценено)", + "overrideError": "Не удалось обновить статус", + "noteError": "Не удалось сохранить заметку", + "notes": { + "title": "Заметки", + "placeholder": "Добавить заметку…", + "save": "Сохранить", + "cancel": "Отмена" + }, + "reasonModal": { + "title": "Требуется причина", + "description": "Укажите причину изменения статуса. Она будет записана.", + "label": "Причина", + "placeholder": "Объясните, почему меняете статус этого контроля…", + "confirm": "Подтвердить изменение", + "cancel": "Отмена" + }, + "coverageLabel": "Покрытие", + "activityLabel": "Активность", + "evidenceLabel": "Свидетельство", + "seeMore": "Показать больше", + "seeLess": "Показать меньше", + "evaluating": "Оценка фреймворка…", + "complianceScore": "Оценка соответствия", + "generatedAt": "Создан {{date}}", + "reportError": "Не удалось сгенерировать отчёт.", + "coverage": "правил: {{n}}", + "activity": "алертов: {{n}}", + "status": { + "COMPLIANT": "Соответствует", + "NON_COMPLIANT": "Не соответствует", + "AT_RISK": "Под риском", + "NOT_COVERED": "Не покрыт", + "OUT_OF_SCOPE": "Вне области", + "PENDING": "Ожидает", + "label": "Статус", + "NOT_EVALUATED": "Not evaluated" + }, + "toast": { + "toggleError": "Не удалось изменить состояние фреймворка", + "reportGenerated": "Отчёт сгенерирован", + "reportError": "Не удалось сгенерировать отчёт" + }, + "schedule": { + "new": "Новое расписание", + "loading": "Загрузка расписаний…", + "loadError": "Не удалось загрузить расписания.", + "empty": "Расписаний пока нет.", + "edit": "Изменить", + "delete": "Удалить", + "newTitle": "Новое расписание", + "editTitle": "Изменить расписание", + "framework": "Фреймворк", + "cadenceLabel": "Частота", + "cronHint": "Cron из 5 полей (мин час день месяц деньНедели).", + "recipientsHint": "Email через запятую. Оставьте пустым, чтобы только сохранить снимок.", + "save": "Сохранить", + "cancel": "Отмена", + "frameworkRequired": "Фреймворк обязателен", + "cronRequired": "Расписание (cron) обязательно", + "cadence": { + "daily": "Ежедневно", + "weekly": "Еженедельно", + "monthly": "Ежемесячно", + "custom": "Своё" + }, + "toast": { + "saved": "Расписание сохранено", + "saveError": "Не удалось сохранить расписание", + "deleted": "Расписание удалено", + "deleteError": "Не удалось удалить расписание" + }, + "to": "To", + "cc": "Cc", + "toRequired": "At least one recipient is required", + "windowDays": "Reporting window (days)", + "windowDaysShort": "over {{days}}d", + "windowDaysHint": "How far back the report counts. Independent of how often it runs." + }, + "frameworks": { + "new": "Новый фреймворк", + "edit": "Изменить", + "createTitle": "Новый фреймворк", + "visualTab": "Визуально", + "codeTab": "Код", + "key": "Ключ", + "name": "Имя", + "description": "Описание", + "source": "Источник", + "sections": "Разделы", + "sectionKey": "ключ раздела", + "sectionName": "Название раздела", + "requirements": "Требования", + "reqId": "id треб.", + "reqName": "Название требования", + "addSection": "Добавить раздел", + "addRequirement": "Добавить требование", + "satisfiedBy": "выполняется контролями", + "searchControls": "Поиск контролей…", + "noControls": "Нет контролей", + "save": "Сохранить", + "delete": "Удалить", + "confirmDelete": "Подтвердить удаление", + "cancel": "Отмена", + "yamlError": "Не удалось применить YAML: {{error}}", + "keyRequired": "Ключ обязателен", + "nameRequired": "Имя обязательно", + "toast": { + "created": "Фреймворк создан", + "saved": "Фреймворк сохранён", + "saveError": "Не удалось сохранить фреймворк", + "deleted": "Фреймворк удалён", + "deleteError": "Не удалось удалить фреймворк" + }, + "createControl": "Создать новый контроль…", + "createNamed": "Создать контроль «{{name}}»…" + }, + "controls": { + "search": "Поиск контролей…", + "allFamilies": "Все семейства", + "new": "Новый контроль", + "loading": "Загрузка контролей…", + "loadError": "Не удалось загрузить контроли.", + "empty": "Нет подходящих контролей.", + "showingOf": "Показано {{shown}} из {{total}}", + "id": "ID", + "name": "Имя", + "family": "Семейство", + "familyName": "Семейство", + "scope": "Область", + "source": "Источник", + "notInLibrary": "Контроль не найден в библиотеке", + "scopeOpt": { + "data": "Данные", + "governance": "Управление" + }, + "strategy": "Стратегия", + "statement": "Формулировка", + "remediation": "Устранение", + "checks": "Проверки", + "checksHint": "Каждая проверка выполняет SQL-запрос в OpenSearch и применяет правило для решения пройдено/не пройдено.", + "checkKey": "ключ", + "checkName": "Название проверки", + "rule": { + "MIN_HITS_REQUIRED": "Минимум совпадений", + "THRESHOLD_MAX": "Максимальный порог" + }, + "ruleNone": "Без правила", + "ruleValue": "значение", + "addCheck": "Добавить проверку", + "createTitle": "Новый контроль", + "visualTab": "Визуально", + "codeTab": "Код", + "save": "Сохранить", + "delete": "Удалить", + "confirmDelete": "Подтвердить удаление", + "cancel": "Отмена", + "yamlError": "Не удалось применить YAML: {{error}}", + "idRequired": "ID обязателен", + "nameRequired": "Имя обязательно", + "anyDataType": "Any data type", + "addFilter": "Add filter", + "filterField": "log.eventCode", + "filterValue": "value", + "filterValues": "a, b, c", + "toast": { + "created": "Контроль создан", + "saved": "Контроль сохранён", + "saveError": "Не удалось сохранить контроль", + "deleted": "Контроль удалён", + "deleteError": "Не удалось удалить контроль" + } + }, + "doc": { + "title": "Отчёт о соответствии", + "print": "Печать / PDF", + "controlsEvaluated": "Оценено контролей: {{n}}", + "executiveSummary": "Резюме", + "bySection": "Результаты по разделам", + "footer": "{{framework}} — Отчёт о соответствии создан {{date}} · {{brand}}", + "download": "Скачать PDF", + "downloadError": "Не удалось скачать PDF", + "error": "Не удалось создать PDF", + "building": "Создание документа…" + }, + "locked": { + "badge": "Enterprise", + "upgrade": "Перейти на Enterprise", + "upsell": "Этот фреймворк/контроль требует редакции Enterprise." + }, + "run": "Run evaluation", + "runError": "Evaluation failed", + "noReportYet": "This framework has not been evaluated yet.", + "window": "window {{from}} → {{to}}", + "scoredOver": "{{compliant}} of {{evaluated}} requirements met · {{total}} in the framework", + "editStale": "Recorded when the engine said {{was}}; it now says {{now}}", + "checkResults": "Check results", + "verdict": "Recorded verdict", + "engineSaid": "engine said", + "hits": "hits", + "noDataFor": "no {{dataType}} data in the window", + "setStatus": "Set status", + "outcome": { + "PASSED": "Passed", + "FAILED": "Failed", + "NOT_APPLICABLE": "No data", + "ERROR": "Error" + }, + "system": "Поставляется", + "addNote": "Добавить заметку", + "noteModal": { + "title": "Заметка", + "description": "Записывается в отчёт. Не меняет статус контроля.", + "placeholder": "Исправление в работе — тикет OPS-4412." + }, + "history": { + "title": "Динамика оценки", + "score": "Оценка соответствия", + "coverage": "Оценено", + "error": "Не удалось загрузить историю" + } }, - "console": { - "section": "Консоль", - "sectionHint": "Выполняйте команды на этом хосте через его агент (живой отклик).", - "open": "Открыть консоль", - "close": "Закрыть", - "hint": "Введите команду и нажмите Enter, чтобы выполнить её на агенте.", - "running": "Выполнение…", - "placeholder": "Введите команду…", - "offline": "Похоже, этот агент офлайн — он может не отвечать на команды.", - "vars": { - "button": "Переменные", - "title": "Переменные команд", - "subtitle": "Ссылайтесь на них в командах как", - "add": "Новая переменная", - "name": "Имя", - "value": "Значение", - "description": "Описание", - "isSecret": "Секрет (зашифрован, скрыт в выводе)", - "secret": "секрет", - "secretHint": "Оставьте пустым, чтобы сохранить хранимое значение.", + "languageSettings": { + "title": "Язык платформы", + "subtitle": "Язык интерфейса по умолчанию для экранов до входа, системных писем и новых пользователей. Каждый пользователь может выбрать свой язык в профиле.", + "label": "Язык по умолчанию", + "hint": "Используется, когда пользователь не выбрал собственный язык.", "save": "Сохранить", - "cancel": "Отмена", - "edit": "Изменить", - "delete": "Удалить", - "loading": "Загрузка…", - "empty": "Переменных пока нет.", - "saved": "Переменная сохранена", - "deleted": "Переменная удалена", - "nameRequired": "Необходимо указать имя", - "loadError": "Не удалось загрузить переменные", - "saveError": "Не удалось сохранить переменную", - "deleteError": "Не удалось удалить переменную", - "insert": "Вставить", - "valueRequired": "Требуется значение" - }, - "disabled": "Агент офлайн — команды отключены", - "connError": "Ошибка соединения", - "cmdError": "Ошибка команды", - "shellSelect": "Тип оболочки", - "noRemoteControl": "Этот агент установлен с отключённым удалённым управлением. Он отклоняет команды, и изменить это можно только на самой машине.", - "noRemoteControlShort": "Удалённое управление на этом агенте отключено", - "password": { - "title": "Аутентификация", - "hint": "Пройдите аутентификацию для выполнения команд на этом агенте.", - "tfaPrompt": "Код: ", - "confirm": "ОК", - "cancel": "Отмена", - "authError": "Ошибка аутентификации", - "authHint": "Пройдите аутентификацию для выполнения команд на этом агенте.", - "authOk": "Аутентифицирован." - } - }, - "health": { - "online": "в сети", - "offline": "не в сети", - "total": "всего" - } - }, - "timeRange": { - "quick": "Быстрые диапазоны", - "relative": "Относительный", - "absolute": "Абсолютный", - "last": "Последние", - "apply": "Применить", - "allTime": "Всё время", - "from": "С", - "to": "По", - "now": "сейчас", - "units": { - "minutes": "минут", - "hours": "часов", - "days": "дней", - "weeks": "недель", - "months": "месяцев" - }, - "presets": { - "15m": "Последние 15 минут", - "1h": "Последний час", - "6h": "Последние 6 часов", - "24h": "Последние 24 часа", - "7d": "Последние 7 дней", - "30d": "Последние 30 дней" - } - }, - "alerts": { - "title": "Оповещения", - "matching": "{{count}} совпадений", - "subtitle": "Расставьте приоритеты по важному.", - "openNow": "открыто прямо сейчас.", - "view": { - "alerts": "Оповещения", - "overview": "Обзор" - }, - "toolbar": { - "searchPlaceholder": "Поиск по имени оповещения…", - "allSeverities": "Все уровни серьёзности", - "export": "Экспорт в CSV", - "refresh": "Обновить" - }, - "severity": { - "high": "Высокий", - "medium": "Средний", - "low": "Низкий" - }, - "status": { - "open": "Открыто", - "in_review": "На проверке", - "completed": "Завершено", - "auto": "Автоматическая проверка" - }, - "statusTabs": { - "all": "Все" - }, - "overview": { - "overTime": "Оповещения по времени", - "matchingAlerts": "совпадающих оповещений", - "noData": "Нет данных.", - "bySeverity": "По серьёзности", - "byStatus": "По статусу" - }, - "filters": { - "add": "Добавить фильтр", - "clearAll": "Очистить всё", - "filterValues": "Фильтровать значения…", - "loadingValues": "Загрузка значений…", - "noValues": "Значения не найдены.", - "pickValue": "Выберите значение, чтобы добавить фильтр.", - "empty": "(пусто)", - "cancel": "Отмена", - "addBtn": "Добавить" - }, - "ops": { - "CONTAIN": "содержит", - "IS": "равно", - "IS_NOT": "не равно", - "EXIST": "существует", - "DOES_NOT_EXIST": "не существует" - }, - "fields": { - "adversary_domain": "Домен противника", - "adversary_geolocation_asn": "ASN противника", - "adversary_geolocation_aso": "ASO противника", - "adversary_geolocation_country": "Страна противника", - "adversary_host": "Хост противника", - "adversary_ip": "IP противника", - "adversary_url": "URL противника", - "adversary_user": "Пользователь противника", - "assignee": "Назначено", - "category": "Категория", - "dataSource": "Сенсор", - "dataType": "Тип данных", - "description": "Описание", - "id": "ID", - "impactScore": "Риск", - "impact_availability": "Доступность", - "impact_confidentiality": "Конфиденциальность", - "impact_integrity": "Целостность", - "incidentDetail_incidentName": "Название инцидента", - "incidentDetail_incidentId": "ID инцидента", - "isIncident": "Инцидент", - "name": "Название оповещения", - "notes": "Заметки", - "severity": "Серьёзность", - "status": "Статус", - "tags": "Теги", - "target_domain": "Домен цели", - "target_geolocation_asn": "ASN цели", - "target_geolocation_aso": "ASO цели", - "target_geolocation_country": "Страна цели", - "target_host": "Хост цели", - "target_ip": "IP цели", - "target_url": "URL цели", - "target_user": "Пользователь цели", - "technique": "Техника" - }, - "tagFilter": { - "tags": "Теги", - "tag_one": "{{count}} тег", - "tag_few": "{{count}} тега", - "tag_many": "{{count}} тегов", - "tag_other": "{{count}} тега", - "clearSelection": "Очистить выбор", - "noTags": "Нет тегов" - }, - "bulk": { - "selected": "Выбрано: {{count}}", - "setStatus": "Задать статус", - "addTag": "Добавить тег", - "noTags": "Нет тегов", - "addToIncident": "Добавить в инцидент", - "clear": "Очистить" - }, - "tagEditor": { - "tag": "Тег", - "noTagsYet": "Тегов пока нет", - "createTag": "Создать тег", - "newTagName": "Имя нового тега…", - "createApply": "Создать и применить тег", - "save": "Сохранить", - "cancel": "Отмена", - "edit": "Изменить тег", - "delete": "Удалить тег", - "systemLocked": "Системный тег (заблокирован)", - "alreadyExists": "Такой тег уже существует.", - "color": "Цвет {{color}}", - "createRule": "Создать правило тегирования с этим тегом" - }, - "table": { - "actions": "Действия", - "alert": "Оповещение", - "status": "Статус", - "technique": "Техника", - "severity": "Серьёзность", - "risk": "Риск", - "echoes": "Эхо", - "time": "Время", - "riskHint": "Оценка риска (0–100), окрашена по серьёзности", - "source": "Источник", - "adversary": "Противник" - }, - "row": { - "createRuleFromAlert": "Создать тег из этого оповещения", - "createIncident": "Создать инцидент из этого оповещения", - "viewIncident": "Показать детали инцидента", - "assignedTo": "Назначено: {{user}}", - "echoesTooltip": "{{count}} эхо — нажмите для развёртывания", - "echoesEmpty": "Эхо не зарегистрировано" - }, - "echoes": { - "title": "{{count}} эхо", - "close": "Закрыть", - "empty": "Для этого оповещения нет зарегистрированных эхо.", - "loadError": "Не удалось загрузить эхо." - }, - "list": { - "loading": "Загрузка оповещений…", - "loadError": "Не удалось загрузить оповещения.", - "retry": "Повторить", - "empty": "Нет оповещений, соответствующих этому виду." - }, - "badge": { - "incident": "Инцидент", - "aiAssessed": "Оценено ИИ" - }, - "drawer": { - "setStatus": "Задать статус", - "completeFalsePositive": "Завершить + ложное срабатывание", - "addToIncident": "Добавить в инцидент", - "partOfIncident": "Часть инцидента", - "tabs": { - "summary": "Сводка", - "parties": "Стороны", - "events": "События", - "history": "История" - }, - "section": { - "description": "Описание", - "solution": "Решение", - "references": "Ссылки", - "details": "Подробности", - "yourNotes": "Ваши заметки", - "notes": "Заметки" - }, - "details": { - "severity": "Серьёзность", - "risk": "Риск", - "category": "Категория", - "technique": "Техника", - "sensor": "Сенсор", - "dataType": "Тип данных", - "alertId": "ID оповещения", - "statusNote": "Примечание к статусу", - "assignee": "Исполнитель" - }, - "incidentDetail": { - "incident": "Инцидент", - "id": "ID", - "createdBy": "Создал", - "created": "Создано" - }, - "notesPlaceholder": "Добавьте заметки по расследованию…", - "saveNotes": "Сохранить заметки", - "assignee": "Назначить", - "assign": "Назначить", - "unassign": "Снять назначение", - "unassigned": "Не назначено", - "loadingUsers": "Загрузка пользователей…", - "observationLabel": "Наблюдение", - "observationPlaceholder": "Добавить наблюдение…", - "cancel": "Отмена", - "continue": "Продолжить" - }, - "related": { - "sample": "Выборка до ~11 событий, которые движок сохранил для этого оповещения. Используйте «Показать все связанные журналы» для полного набора без ограничений.", - "loadingEchoes": "Загрузка событий его эхо…", - "sampleWithEchoes": "События, сохранённые в этом оповещении и в его {{count}} эхо (прочитано {{read}}). Используйте «Показать все связанные журналы» для полного набора без ограничений.", - "empty": "Для этого оповещения нет сохранённых событий-образцов. Загрузите полный коррелированный набор в Обозревателе журналов.", - "viewAll": "Показать все связанные журналы" - }, - "party": { - "source": "Источник / цель", - "adversary": "Противник", - "noData": "Нет данных.", - "ip": "IP", - "host": "Хост", - "user": "Пользователь", - "domain": "Домен", - "country": "Страна" - }, - "history": { - "empty": "История не записана.", - "by": "пользователь {{user}}", - "actions": { - "UPDATE_STATUS": "Статус обновлён", - "UPDATE_TAGS": "Теги обновлены", - "UPDATE_NOTES": "Заметки обновлены", - "UPDATE_SOLUTION": "Решение обновлено", - "MARK_AS_INCIDENT": "Отмечено как инцидент" - }, - "detail": { - "statusTo": "Статус → {{status}}", - "tags": "Теги: {{tags}}", - "aiAdded": "Добавлена оценка ИИ", - "observationAdded": "Добавлено наблюдение", - "notesUpdated": "Заметки обновлены" - } - }, - "ai": { - "title": "Оценка ИИ SOC", - "risk": "риск: {{risk}}", - "score": "{{score}}/100", - "generate": "Создать сводку ИИ", - "hint": "SOC-AI исследует это оповещение и добавит оценку.", - "generating": "Анализ оповещения… это может занять минуту.", - "ready": "Сводка ИИ готова", - "failed": "Не удалось создать сводку ИИ", - "slow": "Сводка ИИ формируется дольше ожидаемого. Она появится в оповещении, когда будет готова." - }, - "incident": { - "titleAdd_one": "Добавить {{count}} оповещение в инцидент", - "titleAdd_few": "Добавить {{count}} оповещения в инцидент", - "titleAdd_many": "Добавить {{count}} оповещений в инцидент", - "titleAdd_other": "Добавить {{count}} оповещений в инцидент", - "new": "Новый инцидент", - "existing": "Существующий инцидент", - "nameLabel": "Название инцидента", - "namePlaceholder": "напр. Предполагаемое вторжение Scattered Spider", - "descriptionLabel": "Описание", - "descriptionPlaceholder": "Необязательное краткое описание…", - "pickLabel": "Выберите инцидент", - "loading": "Загрузка…", - "selectPlaceholder": "Выберите инцидент…", - "willLink_one": "Будет связано {{count}} оповещение.", - "willLink_few": "Будут связаны {{count}} оповещения.", - "willLink_many": "Будут связаны {{count}} оповещений.", - "willLink_other": "Будут связаны {{count}} оповещений.", - "cancel": "Отмена", - "create": "Создать инцидент", - "add": "Добавить в инцидент" - }, - "toast": { - "statusUpdated": "Статус обновлён", - "statusFailed": "Не удалось обновить статус", - "tagsUpdated": "Теги обновлены", - "tagsFailed": "Не удалось обновить теги", - "tagCreateFailed": "Не удалось создать тег", - "tagUpdated": "Тег обновлён", - "tagUpdateFailed": "Не удалось обновить тег", - "tagDeleted": "Тег удалён", - "tagDeleteFailed": "Не удалось удалить тег", - "notesSaved": "Заметки сохранены", - "notesFailed": "Не удалось сохранить заметки", - "exportFailed": "Не удалось экспортировать CSV", - "noRelatedLogs": "Связанные журналы для этого оповещения не найдены", - "relatedLogsFailed": "Не удалось загрузить связанные журналы", - "incidentCreated": "Инцидент создан", - "alertsAdded": "Оповещения добавлены в инцидент", - "incidentFailed": "Не удалось сохранить инцидент", - "assigned": "Оповещение назначено", - "unassigned": "Назначение снято", - "assignFailed": "Не удалось обновить исполнителя", - "newAlertsToast_title": "Новые алерты", - "newAlertsToast_count_one": "{{count}} новый алерт", - "newAlertsToast_count_few": "{{count}} новых алерта", - "newAlertsToast_count_many": "{{count}} алертов", - "newAlertsToast_count_other": "{{count}} алерта", - "newAlertsToast_view": "Смотреть" - } - }, - "dataProcessing": { - "live": { - "auto": "Авто" - }, - "pipeline": { - "title": "Конвейер приёма", - "stages": { - "received": "Получено", - "parsed": "Разобрано", - "analyzed": "Проанализировано", - "stored": "Сохранено" - } - }, - "kpi": { - "stored": "Сохранено", - "throughput": "Пропускная способность", - "perMin": "{{value}}/мин", - "survival": "{{rate}}% сохранено", - "received": "Получено", - "dropped": "Отброшено", - "dropRate": "{{rate}}% отброшено" - }, - "chart": { - "title": "Пропускная способность во времени", - "received": "Получено", - "dropped": "Отброшено" - }, - "donut": { - "title": "Состав отбрасывания", - "dropped": "отброшено" - }, - "breakdown": { - "title": "Топ источников и типов", - "bars": "Столбцы", - "treemap": "Treemap", - "showAll": "Показать все {{count}}", - "showLess": "Показать меньше", - "lastSeen": "Последний раз", - "ago": "{{time}} назад" - }, - "title": "Обработка данных", - "subtitle": "Статистика приёма и обработки: полученные события, отброшенные на этапах, а также основные источники и типы.", - "ingestion": { - "title": "Приём данных", - "last24h": "за последние 24 часа", - "noData": "Нет данных в этом окне.", - "loadError": "Не удалось загрузить статистику приёма.", - "groupBy": { - "dataSource": "По источнику данных", - "dataType": "По типу данных" - }, - "status": { - "received": "Получено", - "parsing_dropped": "Отброшено (разбор)", - "analysis_dropped": "Отброшено (анализ)", - "correlation_dropped": "Отброшено (корреляция)", - "all": "Все события" - } - }, - "filters": { - "title": "Фильтры", - "new": "Новый фильтр", - "search": "Поиск по пути…", - "refresh": "Обновить", - "retry": "Повторить", - "empty": "Нет подходящих фильтров.", - "loadError": "Не удалось загрузить фильтры.", - "toggleError": "Не удалось изменить состояние фильтра", - "system": "Системный", - "custom": "Пользовательский", - "systemReadonly": "Системные фильтры доступны только для чтения", - "view": "Просмотр", - "edit": "Изменить", - "ownership": { - "all": "Все", - "system": "Системные", - "custom": "Пользовательские" - }, - "state": { - "all": "Все", - "active": "Активные", - "inactive": "Неактивные" - }, - "col": { - "filter": "Фильтр", - "type": "Тип", - "active": "Активен", - "actions": "Действия" - }, - "pageInfo": "{{from}}–{{to}} из {{count}}" - }, - "editor": { - "createTitle": "Новый фильтр", - "editTitle": "Изменить фильтр", - "viewTitle": "Просмотр фильтра", - "relPath": "Путь", - "relPathHint": "Папка + файл, например syslog/my-filter.yaml", - "content": "Конвейер (YAML)", - "contentHint": "Шаги выполняются по порядку: grok, rename, delete, динамические плагины, …", - "save": "Сохранить", - "saving": "Сохранение…", - "saved": "Фильтр сохранён", - "saveError": "Не удалось сохранить фильтр", - "cancel": "Отмена", - "delete": "Удалить", - "deleteConfirm": "Удалить этот фильтр?", - "deleted": "Фильтр удалён", - "deleteError": "Не удалось удалить фильтр" - }, - "section": { - "overTime": "События во времени", - "top": "Топ", - "dropReasons": "Причины отбрасывания" - } - }, - "incidents": { - "title": "Инциденты", - "subtitle": "Группируйте, сортируйте и закрывайте связанные оповещения как инциденты.", - "refresh": "Обновить", - "count_one": "{{count}} инцидент", - "count_few": "{{count}} инцидента", - "count_many": "{{count}} инцидентов", - "count_other": "{{count}} инцидента", - "openNow": "открыто сейчас", - "empty": "Нет подходящих инцидентов.", - "loadError": "Не удалось загрузить инциденты.", - "retry": "Повторить", - "unassigned": "Не назначен", - "unknownUser": "Неизвестно", - "status": { - "open": "Открыт", - "in_review": "На проверке", - "completed": "Завершён", - "merged": "Объединён" - }, - "sev": { - "high": "Высокая", - "medium": "Средняя", - "low": "Низкая", - "unknown": "Без оценки" - }, - "toolbar": { - "search": "Поиск инцидентов…", - "create": "Создать инцидент", - "allSeverities": "Все уровни серьёзности", - "export": "Экспорт в CSV" - }, - "statusTabs": { - "all": "Все" - }, - "filters": { - "add": "Добавить фильтр", - "clearAll": "Очистить всё", - "filterValues": "Фильтровать значения…", - "loadingValues": "Загрузка значений…", - "noValues": "Значения не найдены.", - "pickValue": "Выберите значение, чтобы добавить фильтр.", - "empty": "(пусто)", - "cancel": "Отмена", - "addBtn": "Добавить" - }, - "ops": { - "IS": "равно" - }, - "layout": { - "table": "Таблица", - "board": "Доска" - }, - "table": { - "name": "Инцидент", - "status": "Статус", - "severity": "Важность", - "assignee": "Ответственный", - "alerts": "Оповещения", - "created": "Создан" - }, - "drawer": { - "created": "Создан {{date}}", - "alertsCount": "{{count}} оповещений", - "solutionPlaceholder": "Решение / заметки по устранению…", - "solutionHint": "Сохраняется при переводе инцидента в «Завершён».", - "tabs": { - "overview": "Обзор", - "alerts": "Оповещения", - "notes": "Заметки", - "history": "История" - }, - "section": { - "description": "Описание", - "solution": "Решение", - "details": "Детали" - }, - "details": { - "id": "ID", - "status": "Статус", - "severity": "Важность", - "assignee": "Ответственный", - "created": "Создан", - "alerts": "Связанные оповещения" - } - }, - "alerts": { - "empty": "К этому инциденту не привязаны оповещения.", - "remove": "Отвязать оповещение", - "removeConfirm": "Отвязать «{{name}}» от этого инцидента?", - "removed": "Оповещение отвязано", - "removeError": "Не удалось отвязать оповещение", - "loadingAlert": "Загрузка оповещения…", - "alertGone": "Этого оповещения больше нет в хранилище — возможно, его удалило хранение.", - "alertFailed": "Не удалось загрузить оповещение.", - "openInAlerts": "Открыть в оповещениях" - }, - "notes": { - "empty": "Заметок пока нет.", - "add": "Добавить заметку", - "addError": "Не удалось добавить заметку", - "placeholder": "Напишите заметку…" - }, - "history": { - "empty": "Истории пока нет." - }, - "toast": { - "statusChanged": "Статус инцидента обновлён", - "statusError": "Не удалось изменить статус", - "exportFailed": "Не удалось экспортировать CSV" - }, - "assign": { - "assign": "Назначить", - "search": "Поиск пользователей…", - "unassign": "Снять назначение", - "noUsers": "Нет пользователей", - "assigned": "Назначено {{user}}", - "unassigned": "Назначение снято", - "error": "Не удалось изменить ответственного", - "custom": "Назначить произвольно", - "customPlaceholder": "Введите логин…" - }, - "action": { - "INCIDENT_CREATED": "Инцидент создан", - "INCIDENT_ALERT_ADD": "Оповещения добавлены", - "INCIDENT_ALERT_STATUS_CHANGED": "Статус оповещений изменён", - "INCIDENT_STATUS_CHANGE": "Статус изменён", - "INCIDENT_NOTE_ADD": "Заметка добавлена", - "INCIDENT_NOTE_CHANGE": "Заметка изменена", - "INCIDENT_ASSIGNED": "Назначение изменено" - }, - "create": { - "title": "Создать инцидент", - "stepIndicator": "Шаг {{current}} из {{total}}", - "selectedCount": "Выбрано оповещений: {{count}}", - "submit": "Создать", - "success": "Инцидент создан", - "error": "Не удалось создать инцидент", - "details": { - "nameLabel": "Название", - "namePlaceholder": "Короткое описательное название", - "descriptionLabel": "Описание", - "descriptionPlaceholder": "Контекст, область, первичные заметки…" - } - } - }, - "alertingRules": { - "title": "Правила оповещений", - "subtitle": "Правила корреляции, превращающие события в оповещения. Включайте, настраивайте или создавайте свои.", - "new": "Новое правило", - "refresh": "Обновить", - "empty": "Нет подходящих правил.", - "loadError": "Не удалось загрузить правила.", - "retry": "Повторить", - "deleteConfirm": "Удалить правило «{{name}}»?", - "adversary": { - "origin": "Источник", - "target": "Цель" - }, - "state": { - "active": "Активно", - "inactive": "Неактивно" - }, - "owner": { - "system": "Системное", - "custom": "Пользовательское" - }, - "toolbar": { - "search": "Поиск правил…", - "allCategories": "Все категории", - "allAdversaries": "Все стороны", - "allStates": "Все состояния", - "allOwners": "Все источники", - "allDataTypes": "Все типы" - }, - "table": { - "name": "Правило", - "category": "Категория", - "technique": "Техника", - "adversary": "Сторона", - "impact": "Влияние", - "active": "Активно", - "dataTypes": "Типы данных", - "selectAll": "Выбрать все", - "selectRow": "Выбрать {{name}}" - }, - "export": { - "all": "Экспортировать все", - "selected": "Экспорт ({{count}})", - "error": "Не удалось экспортировать правила" - }, - "view": { - "description": "Описание", - "details": "Детали", - "impact": "Влияние (К·Ц·Д)", - "dataTypes": "Типы данных", - "updated": "Обновлено", - "relPath": "Путь", - "definition": "Условие (CEL)", - "correlationSteps": "Шаги корреляции", - "correlation": "Корреляция", - "groupBy": "Группировать по", - "deduplicateBy": "Дедупликация по", - "references": "Ссылки" - }, - "editor": { - "createTitle": "Новое правило", - "edit": "Изменить", - "delete": "Удалить", - "export": "Экспортировать", - "cancel": "Отмена", - "save": "Сохранить", - "metadata": "Метаданные", - "name": "Название", - "confidentiality": "Конфиденциальность", - "integrity": "Целостность", - "availability": "Доступность", - "dataTypes": "Типы данных", - "dataTypesHint": "через запятую", - "activeOnSave": "Активно", - "definitionSection": "Определение", - "where": "Условие (CEL)", - "whereHint": "Выражение CEL, вычисляемое для каждого события", - "correlationSteps": "Шаги корреляции", - "correlationStepsHint": "JSON-массив", - "jsonArray": "JSON-массив", - "nameRequired": "Название обязательно", - "definitionRequired": "Условие обязательно", - "invalidJson": "В поле определения некорректный JSON", - "addStep": "Добавить шаг корреляции", - "step": "Шаг {{n}}", - "removeStep": "Удалить шаг", - "indexPattern": "Шаблон индекса", - "within": "Окно", - "count": "Количество", - "conditions": "Условия", - "field": "Поле", - "value": "Значение", - "addCondition": "Добавить условие", - "orGroup": "Группа Or {{n}}", - "addOr": "Добавить группу Or", - "removeOr": "Удалить", - "fieldsHint": "имена полей", - "referencesHint": "URL", - "visual": "Визуально", - "code": "Код", - "dataTypesPick": "Выбрать…", - "dataTypesSearch": "Поиск типов данных…", - "dataTypesNone": "Нет типов данных", - "visualTab": "Визуально", - "codeTab": "Код", - "yamlError": "Не удалось применить YAML: {{error}}", - "test": "Test" - }, - "toast": { - "activated": "Правило включено", - "deactivated": "Правило выключено", - "toggleError": "Не удалось изменить состояние правила", - "deleted": "Правило удалено", - "deleteError": "Не удалось удалить правило", - "created": "Правило создано", - "saved": "Правило сохранено", - "saveError": "Не удалось сохранить правило" - }, - "operator": { - "filter_term": "равно (term)", - "must_not_term": "не равно (term)", - "filter_match": "совпадает (текст)", - "must_not_match": "не совпадает (текст)" - }, - "where": { - "matchPrefix": "Соответствует", - "all": "всем", - "any": "любому", - "matchSuffix": "из этих условий:", - "negate": "Отрицать", - "listHint": "через запятую", - "advanced": "Это условие использует сложный CEL — измените его в режиме «Код» или соберите заново визуально.", - "and": "И", - "or": "ИЛИ" - }, - "celOp": { - "exists": "существует", - "equals": "равно", - "equalsIgnoreCase": "равно (без регистра)", - "contains": "содержит", - "oneOf": "одно из", - "containsAll": "содержит все", - "startsWith": "начинается с", - "endsWith": "заканчивается на", - "regexMatch": "regex", - "lessThan": "<", - "lessOrEqual": "≤", - "greaterThan": ">", - "greaterOrEqual": "≥", - "inCIDR": "в CIDR", - "isHour": "час равен", - "isMinute": "минута равна", - "isDayOfWeek": "день недели", - "isWeekend": "выходной", - "isWorkDay": "рабочий день", - "isBetweenTime": "время между" - }, - "import": { - "button": "Импорт", - "error": "Сбой импорта", - "resultTitle": "Результаты импорта", - "approved": "Одобрено", - "rejected": "Отклонено", - "done": "Готово" - }, - "test": "Test" - }, - "regexPatterns": { - "title": "Регулярные выражения", - "subtitle": "Многоразовые регулярные выражения, на которые ссылаются фильтры разбора.", - "new": "Новый шаблон", - "search": "Поиск шаблонов…", - "refresh": "Обновить", - "view": "Просмотр", - "system": "Системный", - "user": "Пользовательский", - "loading": "Загрузка шаблонов…", - "loadError": "Не удалось загрузить шаблоны.", - "retry": "Повторить", - "empty": "Нет шаблонов для этого представления.", - "tabs": { - "all": "Все", - "system": "Системные", - "user": "Пользовательские" - }, - "cols": { - "pattern": "Шаблон", - "definition": "Определение", - "type": "Тип" - }, - "editor": { - "titleNew": "Новый шаблон", - "patternId": "ID шаблона", - "patternIdHint": "Уникальное имя, на которое ссылаются фильтры.", - "description": "Описание", - "descriptionPlaceholder": "Что распознаёт этот шаблон (необязательно)", - "definition": "Определение (regex)", - "definitionHint": "Регулярное выражение. Может ссылаться на другие шаблоны.", - "readOnly": "Системный шаблон — только чтение.", - "save": "Сохранить", - "saving": "Сохранение…", - "delete": "Удалить", - "confirmDelete": "Подтвердить удаление", - "cancel": "Отмена" - }, - "toast": { - "saved": "Шаблон сохранён", - "saveError": "Не удалось сохранить шаблон", - "deleted": "Шаблон удалён", - "deleteError": "Не удалось удалить шаблон", - "patternIdRequired": "ID шаблона обязателен", - "definitionRequired": "Определение обязательно" - } - }, - "parsingFilters": { - "title": "Пайплайны", - "subtitle": "YAML-пайплайны, применяемые к логам при их разборе во время приёма.", - "new": "Новый пайплайн", - "search": "Поиск пайплайнов…", - "refresh": "Обновить", - "view": "Просмотр", - "system": "Системный", - "user": "Свои", - "loading": "Загрузка пайплайнов…", - "loadError": "Не удалось загрузить пайплайны.", - "retry": "Повторить", - "empty": "Нет пайплайнов для этого вида.", - "tabs": { - "all": "Все", - "active": "Активные", - "inactive": "Неактивные", - "system": "Системные", - "user": "Свои" - }, - "cols": { - "filter": "Пайплайн", - "type": "Тип", - "active": "Активен", - "dataTypes": "Типы данных", - "order": "Порядок", - "moveUp": "Переместить вверх", - "moveDown": "Переместить вниз", - "actions": "Действия" - }, - "editor": { - "titleNew": "Новый пайплайн", - "titleEdit": "Редактировать пайплайн", - "titleSystem": "Пайплайн (системный)", - "name": "Имя", - "namePlaceholder": "Мой собственный пайплайн", - "nameHint": "Будет сохранено как {{file}}", - "namePending": "Выберите имя — оно станет именем файла.", - "content": "Содержимое (pipeline YAML)", - "contentHint": "Корректное определение в формате pipeline: YAML.", - "readOnly": "Системный пайплайн — только для чтения. Можно лишь включить или отключить.", - "save": "Сохранить", - "saving": "Сохранение…", - "delete": "Удалить", - "confirmDelete": "Подтвердить удаление", - "cancel": "Отмена", - "test": "Test" - }, - "toast": { - "saved": "Пайплайн сохранён", - "saveError": "Не удалось сохранить пайплайн", - "deleted": "Пайплайн удалён", - "deleteError": "Не удалось удалить пайплайн", - "activateError": "Не удалось изменить состояние пайплайна", - "nameRequired": "Имя обязательно", - "contentRequired": "Содержимое обязательно", - "orderError": "Не удалось изменить порядок пайплайна" - }, - "visual": { - "visualTab": "Визуально", - "codeTab": "Код", - "codeOnly": "Переключитесь на Код — это содержимое нельзя показать визуально.", - "cantParse": "Не удалось открыть визуальный редактор: {{error}}", - "dataTypes": "Типы данных", - "steps": "Шаги", - "noSteps": "Пока нет шагов.", - "addStep": "Добавить шаг:", - "removeStep": "Удалить шаг", - "moveUp": "Вверх", - "moveDown": "Вниз", - "whereHint": "необязательное условие (CEL)", - "addValue": "Добавить значение", - "addPattern": "Добавить шаблон", - "rawHint": "Этот процессор редактируется как сырой YAML.", - "rawNotMap": "Должен быть набор полей ключ: значение.", - "dataTypesPick": "Выбрать типы данных", - "dataTypesSearch": "Поиск типов данных…", - "dataTypesNone": "Нет типов данных", - "dataTypesAdd": "Добавить «{{value}}»", - "insertPattern": "Вставить regex-шаблон", - "patternSearch": "Поиск шаблонов…", - "patternNone": "Нет шаблонов", - "newPattern": "Новый шаблон…", - "createInsert": "Создать и вставить", - "patternCreated": "Шаблон «{{name}}» создан", - "patternCreateError": "Не удалось создать шаблон", - "patternIdInvalid": "ID шаблона должен начинаться с буквы или _ и содержать только буквы, цифры или _", - "patternDefRequired": "Определение обязательно", - "parameters": "Параметры", - "paramsKey": "Ключ", - "paramsValue": "Значение", - "entry": "Запись {{n}}", - "order": "порядок {{n}}", - "orderLabel": "Порядок", - "removeEntry": "Удалить запись", - "addEntry": "Добавить запись пайплайна", - "collapse": "Свернуть", - "expand": "Развернуть", - "splitHint": "Vacío equivale a un espacio por defecto — en el YAML siempre aparece como fieldSplit: \" \"." - }, - "allDataTypes": "Все типы данных", - "testPipeline": "Test pipeline" - }, - "soar": { - "title": "SOAR", - "subtitle": "Автоматические потоки реагирования: условия совпадают с алертом, команды выполняются на агенте.", - "comingSoon": "Скоро появится", - "console": { - "loading": "Загрузка агентов…", - "loadError": "Не удалось загрузить агентов.", - "pickAgent": "Выберите агента", - "pickAgentHint": "Выберите агента из списка, чтобы открыть его интерактивную консоль.", - "lockedAgent": "Удалённое управление отключено" - }, - "search": "Поиск потоков…", - "refresh": "Обновить", - "new": "Новый поток", - "view": "Просмотр", - "system": "Системный", - "loading": "Загрузка потоков…", - "loadError": "Не удалось загрузить потоки.", - "retry": "Повторить", - "empty": "Нет потоков для этого вида.", - "templates": { - "title": "Новый поток", - "subtitle": "Выберите шаблон действия или начните с нуля.", - "loading": "Загрузка шаблонов…", - "loadError": "Не удалось загрузить шаблоны.", - "empty": "Шаблоны отсутствуют.", - "cancel": "Отмена", - "scratch": "Начать с нуля" - }, - "tabs": { - "flows": "Потоки", - "executions": "История выполнений", - "all": "Все", - "active": "Активные", - "inactive": "Неактивные", - "system": "Системные", - "user": "Свои" - }, - "cols": { - "flow": "Поток", - "platform": "Платформа", - "conditions": "Условия", - "commands": "Команды", - "active": "Активен", - "lastRun": "Последний запуск", - "failedRuns_one": "{{count}} неудачный запуск", - "failedRuns_other": "{{count}} неудачных запусков" - }, - "operator": { - "IS": "равно", - "IS_NOT": "не равно", - "CONTAINS": "содержит", - "NOT_CONTAINS": "не содержит", - "EXISTS": "существует", - "NOT_EXISTS": "не существует", - "START_WITH": "начинается с", - "NOT_START_WITH": "не начинается с", - "ENDS_WITH": "заканчивается на", - "NOT_ENDS_WITH": "не заканчивается на", - "IS_ONE_OF": "одно из", - "IS_NOT_ONE_OF": "не одно из" - }, - "toast": { - "created": "Поток создан", - "saved": "Поток сохранён", - "saveError": "Не удалось сохранить поток", - "deleted": "Поток удалён", - "deleteError": "Не удалось удалить поток", - "activateError": "Не удалось изменить состояние потока" - }, - "editor": { - "createTitle": "Новый поток", - "visualTab": "Визуально", - "codeTab": "Код", - "name": "Имя", - "description": "Описание", - "conditions": "Условия", - "conditionsHint": "Поток запускается, когда алерт удовлетворяет ВСЕМ этим условиям.", - "field": "поле", - "value": "значение", - "valueList": "значения через запятую", - "addCondition": "Добавить условие", - "commands": "Команды", - "commandsHint": "Выполняются по порядку на агенте. Используйте $(field.path) для значений алерта и $[variables.NAME] для сохранённых переменных.", - "addCommand": "Добавить команду", - "templatesButton": "Частые команды", - "templates": { - "isolate": "Изолировать от сети", - "shutdown": "Выключить машину", - "killProcess": "Завершить процесс", - "logout": "Завершить сеанс пользователя", - "disableUser": "Отключить пользователя", - "blockIp": "Заблокировать IP", - "restart": "Перезагрузить машину", - "uninstall": "Удалить приложение" - }, - "connector": { - "always": "всегда", - "success": "при успехе", - "failure": "при ошибке" - }, - "agentPlatform": "Платформа агента", - "shell": "Оболочка", - "shellAuto": "авто", - "whereToRun": "Где выполнять", - "run": { - "all": "Все агенты", - "specific": "Один агент", - "except": "Все, кроме", - "allHint": "Выполняется на всех агентах, соответствующих этой платформе." - }, - "selectAgentPlaceholder": "Выберите агента…", - "excludedAgentsHint": "введите имя хоста и нажмите Enter", - "save": "Сохранить", - "delete": "Удалить", - "confirmDelete": "Подтвердить удаление", - "cancel": "Отмена", - "yamlError": "Не удалось применить YAML: {{error}}", - "nameRequired": "Имя обязательно", - "conditionsRequired": "Требуется хотя бы одно условие с полем", - "commandsRequired": "Требуется хотя бы одна команда", - "httpUrlInvalid": "Узел HTTP \"{{id}}\" содержит недопустимый URL — должен быть допустимый http(s) URL.", - "httpBodyInvalid": "Тело узла HTTP \"{{id}}\" не является допустимым JSON: {{error}}", - "incidentNameRequired": "Узлу инцидента \"{{id}}\" требуется имя.", - "mailToRequired": "Узлу электронной почты \"{{id}}\" требуется хотя бы один получатель.", - "mailAddressInvalid": "Узел электронной почты \"{{id}}\" содержит недопустимый адрес {{field}}: {{address}}.", - "mailSubjectRequired": "Узлу электронной почты \"{{id}}\" требуется тема.", - "identityModalTitle": "Свойства потока", - "platformRequired": "Платформа агента обязательна", - "nameLabel": "Название", - "namePlaceholder": "Имя потока", - "descriptionLabel": "Описание", - "descriptionHint": "Что делает этот поток? (необязательно)", - "when": "Когда", - "whenTitle": "Алерт удовлетворяет всем этим условиям", - "on": "На", - "onTitle": "Совпавший агент", - "thenRun": "Тогда выполнить", - "thenTitle": "Эти команды, по порядку", - "selectField": "Выберите поле…", - "selectPlatform": "Выберите платформу…", - "searchAgents": "Поиск агентов…", - "noAgents": "Нет агентов", - "insertInto": "Вставить в команду {{n}}:", - "insertField": "Поле алерта", - "variables": "Переменные", - "canvas": { - "node": "Узел", - "deleteNode": "Удалить узел", - "id": "ID", - "kind": "Тип", - "executor": "Исполнитель", - "commandLabel": "Команда", - "paramsJson": "Параметры (JSON)", - "dragToResize": "Потяните, чтобы изменить размер", - "templatesLabel": "Шаблоны", - "templatesNeedPlatform": "Сначала выберите целевую платформу", - "handlesHint": "Потяните от зелёного разъёма (снизу слева) для on_success и от красного (снизу справа) для on_error. Несколько связей = параллельно. Несколько связей к одному узлу = AND-join.", - "invalidJson": "недопустимый JSON", - "hidePalette": "Скрыть палитру", - "hideInspector": "Скрыть инспектор", - "paletteLabel": "Палитра", - "nodeShort": "Узел", - "showPanel": "Показать {{name}}", - "platform": "Платформа", - "shell": "Оболочка", - "any": "любая", - "auto": "авто", - "runOn": "Запуск на", - "runAutoTitle": "Запускается на хосте, где сработало предупреждение", - "runSpecificTitle": "Закрепить за одним хостом (или шаблоном вида $(alert.foo))", - "runExceptTitle": "Запускается на хосте, где сработало предупреждение, но пропускает указанные в списке", - "runAutoLabel": "источник алерта", - "runSpecificLabel": "один хост", - "runExceptLabel": "все кроме", - "runAutoHint": "Запускается на $(alert.dataSource) — хосте, где сработало предупреждение.", - "pickHost": "выберите хост…", - "orTemplateHint": "Или введите шаблон — $(alert.field) вычисляется при каждом запуске.", - "addExclusion": "добавить исключение", - "searchAgents": "поиск агентов…", - "noAgents": "нет агентов", - "insertField": "Вставить поле", - "alert": "Алерт", - "wholeOutput": "весь вывод (отредактируйте путь)", - "noAncestorsHint": "Пока нет предков обогащения — добавьте узел обогащения выше по цепочке, чтобы его вывод стал доступен здесь.", - "inserts": "вставляет", - "conditionalHint": "Все условия должны совпадать. Совпадение → ветвь успеха (зелёная); несовпадение → ветвь ошибки (красная).", - "http": { - "url": "URL", - "urlInvalid": "Недопустимый http(s) URL.", - "method": "Метод", - "body": "Тело (JSON)", - "bodyInvalid": "Недопустимый JSON", - "headers": "HTTP-заголовки", - "params": "Параметры запроса", - "key": "Ключ", - "value": "Значение", - "addHeader": "Добавить заголовок", - "addParam": "Добавить параметр" + "saving": "Сохранение…", + "saved": "Язык платформы обновлён", + "loadError": "Не удалось загрузить настройку языка", + "saveError": "Не удалось сохранить настройку языка" + }, + "branding": { + "title": "Брендинг", + "subtitle": "Оформите UTMStack под фирменный стиль вашей организации — он применяется везде: на экране входа, в боковой панели, письмах и отчётах.", + "enterpriseRequired": "Брендинг под вашим именем — функция Enterprise.", + "manageLicense": "Управление лицензией", + "enable": { + "title": "Брендинг под вашим именем", + "description": "Замените бренд UTMStack своим во всей платформе.", + "label": "Включить брендинг под вашим именем" }, - "incident": { - "name": "Название инцидента", - "namePlaceholder": "Напр. Подозрительный вход на $(alert.dataSource)", - "description": "Описание", - "descriptionPlaceholder": "Дополнительный контекст для отвечающих. Шаблоны вроде $(alert.name) подставляются." - }, - "llm": { - "prompt": "Промпт", - "hint": "Модель всегда отвечает одним JSON-объектом со свойством \"result\"; backend гарантирует этот формат даже если модель отклоняется. Дочерние узлы обращаются к нему через $({{nodeId}}.result) или конкретные поля." - }, - "mail": { - "to": "Кому (через запятую)", - "cc": "Копия (через запятую, опционально)", - "addressInvalid": "Недопустимый адрес электронной почты: {{address}}", - "subject": "Тема", - "subjectPlaceholder": "Напр. Тревога на $(alert.dataSource)", - "body": "Текст", - "bodyPlaceholder": "Содержимое сообщения. Шаблоны вроде $(alert.name) подставляются." - }, - "notify": { - "level": "Level", - "message": "Message", - "messagePlaceholder": "Notification text. Templates like $(alert.name) are interpolated." + "identity": { + "title": "Идентичность", + "productName": "Название продукта", + "productNameHint": "Отображается в заголовке окна, боковой панели и письмах.", + "accent": "Акцентный цвет", + "accentHint": "Основной цвет для кнопок, ссылок и активных состояний.", + "custom": "Свой цвет" + }, + "logos": { + "title": "Логотипы", + "hint": "PNG, SVG, WEBP, JPG или ICO. До 5 МБ.", + "logo": "Логотип (светлый)", + "logoDark": "Логотип (тёмный)", + "favicon": "Фавикон" + }, + "reports": { + "title": "Ресурсы отчётов", + "hint": "Встраиваются в создаваемые PDF-отчёты.", + "reportLogo": "Логотип отчёта", + "reportCover": "Обложка отчёта" + }, + "asset": { + "upload": "Загрузить", + "replace": "Заменить" + }, + "save": "Сохранить изменения", + "saving": "Сохранение…", + "saved": "Брендинг обновлён", + "saveError": "Не удалось сохранить брендинг", + "uploaded": "Изображение загружено", + "uploadError": "Не удалось загрузить изображение", + "loadError": "Не удалось загрузить брендинг", + "enterprise": { + "title": "Белая метка — функция Enterprise", + "body": "Замените название продукта, логотип и обложку отчётов на свои, чтобы панель и всё, что она создаёт, несли ваш бренд, а не UTMStack.", + "upgrade": "Перейти на Enterprise" + }, + "restore": "Восстановить значения UTMStack", + "restored": "Оформление восстановлено к значениям UTMStack" + }, + "emailConfig": { + "title": "Настройка электронной почты", + "subtitle": "SMTP-сервер для отправки уведомлений об угрозах, отчётов и писем по учётным записям.", + "server": { + "title": "SMTP-сервер", + "host": "Хост", + "hostHint": "Имя хоста вашего SMTP-сервера.", + "port": "Порт", + "encryption": "Шифрование", + "username": "Имя пользователя", + "password": "Пароль", + "passwordSetHint": "Пароль сохранён. Оставьте поле пустым, чтобы сохранить его, или введите новый, чтобы изменить." + }, + "encryptionOpt": { + "TLS": "TLS", + "SSL": "SSL", + "NONE": "Нет" + }, + "sender": { + "title": "Отправитель", + "from": "Адрес отправителя", + "fromHint": "Адрес, с которого отправляются письма.", + "organization": "Название организации", + "organizationHint": "Отображается в письмах об угрозах и инцидентах.", + "baseUrl": "Базовый URL", + "baseUrlHint": "Публичный URL этого экземпляра, используется для ссылок в письмах." + }, + "test": { + "button": "Отправить тест", + "sending": "Отправка…", + "sentTo": "Тестовое письмо будет отправлено на {{email}}.", + "success": "Тестовое письмо отправлено на {{email}}", + "fail": "Не удалось отправить тестовое письмо", + "fromRequired": "Укажите адрес отправителя перед тестированием" + }, + "save": "Сохранить изменения", + "saving": "Сохранение…", + "saved": "Настройка электронной почты сохранена", + "saveError": "Не удалось сохранить настройку", + "loadError": "Не удалось загрузить настройку", + "recipients": { + "alertsTitle": "Получатели оповещений", + "incidentsTitle": "Получатели инцидентов", + "to": "Кому", + "cc": "Копия", + "alertsHelper": "Адреса, на которые приходят новые оповещения. Если оставить пустым, оповещения по почте не отправляются.", + "incidentsHelper": "Адреса, на которые приходит уведомление о создании инцидента. Если оставить пустым, уведомления по почте не отправляются.", + "add": "Добавить" } - } - }, - "executions": { - "search": "Поиск по ID алерта…", - "all": "Все", - "loading": "Загрузка выполнений…", - "loadError": "Не удалось загрузить выполнения.", - "retry": "Повторить", - "empty": "Пока нет выполнений.", - "cols": { - "status": "Статус", - "flow": "Поток", - "command": "Команда / Действие", - "agent": "Агент", - "date": "Дата", - "retries": "Попытки", - "node": "Узел" - }, - "manual": "Интерактивная консоль", - "filters": { - "source": "Source", - "allSources": "All sources" - } - }, - "executionStatus": { - "WAITING": "В ожидании", - "PENDING": "В очереди", - "EXECUTING": "Выполняется", - "EXECUTED": "Выполнено", - "FAILED": "Ошибка", - "DEAD": "Недостижимо" - }, - "nonExecutionCause": { - "AGENT_OFFLINE": "Агент офлайн", - "AGENT_NOT_FOUND": "Агент не найден", - "UNKNOWN": "Неизвестно" - }, - "kpi": { - "flows": "Всего потоков", - "active": "Активные", - "runs24h": "Выполнения (24 ч)", - "failed24h": "Неудачные (24 ч)" - }, - "neverRun": "никогда", - "create": { - "title": "Новый поток", - "modeManual": "Создать вручную", - "modeAi": "С помощью ИИ", - "aiLocked": "Включите SOC-AI и настройте его, чтобы использовать это.", - "name": "Имя потока", - "namePlaceholder": "напр. Заблокировать IP при повторных сбоях", - "aiDescriptionLabel": "Что должен делать этот поток?", - "aiDescriptionPlaceholder": "напр. При критическом оповещении найти исходный IP в разведданных и заблокировать его на файрволе", - "aiCreate": "Создать с ИИ", - "manualContinue": "Продолжить" - }, - "executionOrigin": { - "FLOW": "Flow", - "MANUAL": "Manual" - } - }, - "compliance": { - "title": "Compliance", - "subtitle": "Оцените соответствие фреймворкам безопасности — какие контроли выполнены, а какие нет.", - "comingSoon": "Скоро.", - "tabs": { - "frameworks": "Фреймворки", - "schedule": "Расписание", - "controls": "Контроли" - }, - "search": "Поиск фреймворков…", - "refresh": "Refresh", - "loading": "Загрузка фреймворков…", - "loadError": "Could not load reports", - "retry": "Повторить", - "empty": "Нет подходящих фреймворков.", - "notEvaluated": "Не оценён", - "controlsCount": "Контролей: {{n}}", - "enabledLabel": "Включён", - "runReport": "Запустить отчёт", - "backToFrameworks": "К фреймворкам", - "statusAuto": "Авто (оценено)", - "overrideError": "Не удалось обновить статус", - "noteError": "Не удалось сохранить заметку", - "notes": { - "title": "Заметки", - "placeholder": "Добавить заметку…", - "save": "Сохранить", - "cancel": "Отмена" - }, - "reasonModal": { - "title": "Требуется причина", - "description": "Укажите причину изменения статуса. Она будет записана.", - "label": "Причина", - "placeholder": "Объясните, почему меняете статус этого контроля…", - "confirm": "Подтвердить изменение", - "cancel": "Отмена" - }, - "coverageLabel": "Покрытие", - "activityLabel": "Активность", - "evidenceLabel": "Свидетельство", - "seeMore": "Показать больше", - "seeLess": "Показать меньше", - "evaluating": "Оценка фреймворка…", - "complianceScore": "Оценка соответствия", - "generatedAt": "Создан {{date}}", - "reportError": "Не удалось сгенерировать отчёт.", - "coverage": "правил: {{n}}", - "activity": "алертов: {{n}}", - "status": { - "COMPLIANT": "Соответствует", - "NON_COMPLIANT": "Не соответствует", - "AT_RISK": "Под риском", - "NOT_COVERED": "Не покрыт", - "OUT_OF_SCOPE": "Вне области", - "PENDING": "Ожидает", - "label": "Статус", - "NOT_EVALUATED": "Not evaluated" - }, - "toast": { - "toggleError": "Не удалось изменить состояние фреймворка", - "reportGenerated": "Отчёт сгенерирован", - "reportError": "Не удалось сгенерировать отчёт" - }, - "schedule": { - "new": "Новое расписание", - "loading": "Загрузка расписаний…", - "loadError": "Не удалось загрузить расписания.", - "empty": "Расписаний пока нет.", - "edit": "Изменить", - "delete": "Удалить", - "newTitle": "Новое расписание", - "editTitle": "Изменить расписание", - "framework": "Фреймворк", - "cadenceLabel": "Частота", - "cronHint": "Cron из 5 полей (мин час день месяц деньНедели).", - "recipientsHint": "Email через запятую. Оставьте пустым, чтобы только сохранить снимок.", - "save": "Сохранить", - "cancel": "Отмена", - "frameworkRequired": "Фреймворк обязателен", - "cronRequired": "Расписание (cron) обязательно", - "cadence": { - "daily": "Ежедневно", - "weekly": "Еженедельно", - "monthly": "Ежемесячно", - "custom": "Своё" - }, - "toast": { - "saved": "Расписание сохранено", - "saveError": "Не удалось сохранить расписание", - "deleted": "Расписание удалено", - "deleteError": "Не удалось удалить расписание" - }, - "to": "To", - "cc": "Cc", - "toRequired": "At least one recipient is required", - "windowDays": "Reporting window (days)", - "windowDaysShort": "over {{days}}d", - "windowDaysHint": "How far back the report counts. Independent of how often it runs." - }, - "frameworks": { - "new": "Новый фреймворк", - "edit": "Изменить", - "createTitle": "Новый фреймворк", - "visualTab": "Визуально", - "codeTab": "Код", - "key": "Ключ", - "name": "Имя", - "description": "Описание", - "source": "Источник", - "sections": "Разделы", - "sectionKey": "ключ раздела", - "sectionName": "Название раздела", - "requirements": "Требования", - "reqId": "id треб.", - "reqName": "Название требования", - "addSection": "Добавить раздел", - "addRequirement": "Добавить требование", - "satisfiedBy": "выполняется контролями", - "searchControls": "Поиск контролей…", - "noControls": "Нет контролей", - "save": "Сохранить", - "delete": "Удалить", - "confirmDelete": "Подтвердить удаление", - "cancel": "Отмена", - "yamlError": "Не удалось применить YAML: {{error}}", - "keyRequired": "Ключ обязателен", - "nameRequired": "Имя обязательно", - "toast": { - "created": "Фреймворк создан", - "saved": "Фреймворк сохранён", - "saveError": "Не удалось сохранить фреймворк", - "deleted": "Фреймворк удалён", - "deleteError": "Не удалось удалить фреймворк" - }, - "createControl": "Создать новый контроль…", - "createNamed": "Создать контроль «{{name}}»…" - }, - "controls": { - "search": "Поиск контролей…", - "allFamilies": "Все семейства", - "new": "Новый контроль", - "loading": "Загрузка контролей…", - "loadError": "Не удалось загрузить контроли.", - "empty": "Нет подходящих контролей.", - "showingOf": "Показано {{shown}} из {{total}}", - "id": "ID", - "name": "Имя", - "family": "Семейство", - "familyName": "Семейство", - "scope": "Область", - "source": "Источник", - "notInLibrary": "Контроль не найден в библиотеке", - "scopeOpt": { - "data": "Данные", - "governance": "Управление" - }, - "strategy": "Стратегия", - "statement": "Формулировка", - "remediation": "Устранение", - "checks": "Проверки", - "checksHint": "Каждая проверка выполняет SQL-запрос в OpenSearch и применяет правило для решения пройдено/не пройдено.", - "checkKey": "ключ", - "checkName": "Название проверки", - "rule": { - "MIN_HITS_REQUIRED": "Минимум совпадений", - "THRESHOLD_MAX": "Максимальный порог" - }, - "ruleNone": "Без правила", - "ruleValue": "значение", - "addCheck": "Добавить проверку", - "createTitle": "Новый контроль", - "visualTab": "Визуально", - "codeTab": "Код", - "save": "Сохранить", - "delete": "Удалить", - "confirmDelete": "Подтвердить удаление", - "cancel": "Отмена", - "yamlError": "Не удалось применить YAML: {{error}}", - "idRequired": "ID обязателен", - "nameRequired": "Имя обязательно", - "anyDataType": "Any data type", - "addFilter": "Add filter", - "filterField": "log.eventCode", - "filterValue": "value", - "filterValues": "a, b, c", - "toast": { - "created": "Контроль создан", - "saved": "Контроль сохранён", - "saveError": "Не удалось сохранить контроль", - "deleted": "Контроль удалён", - "deleteError": "Не удалось удалить контроль" - } }, - "doc": { - "title": "Отчёт о соответствии", - "print": "Печать / PDF", - "controlsEvaluated": "Оценено контролей: {{n}}", - "executiveSummary": "Резюме", - "bySection": "Результаты по разделам", - "footer": "{{framework}} — Отчёт о соответствии создан {{date}} · {{brand}}", - "download": "Скачать PDF", - "downloadError": "Не удалось скачать PDF", - "error": "Не удалось создать PDF", - "building": "Создание документа…" - }, - "locked": { - "badge": "Enterprise", - "upgrade": "Перейти на Enterprise", - "upsell": "Этот фреймворк/контроль требует редакции Enterprise." - }, - "run": "Run evaluation", - "runError": "Evaluation failed", - "noReportYet": "This framework has not been evaluated yet.", - "window": "window {{from}} → {{to}}", - "scoredOver": "{{compliant}} of {{evaluated}} requirements met · {{total}} in the framework", - "editStale": "Recorded when the engine said {{was}}; it now says {{now}}", - "checkResults": "Check results", - "verdict": "Recorded verdict", - "engineSaid": "engine said", - "hits": "hits", - "noDataFor": "no {{dataType}} data in the window", - "setStatus": "Set status", - "outcome": { - "PASSED": "Passed", - "FAILED": "Failed", - "NOT_APPLICABLE": "No data", - "ERROR": "Error" - }, - "system": "Поставляется", - "addNote": "Добавить заметку", - "noteModal": { - "title": "Заметка", - "description": "Записывается в отчёт. Не меняет статус контроля.", - "placeholder": "Исправление в работе — тикет OPS-4412." - }, - "history": { - "title": "Динамика оценки", - "score": "Оценка соответствия", - "coverage": "Оценено", - "error": "Не удалось загрузить историю" - } - }, - "languageSettings": { - "title": "Язык платформы", - "subtitle": "Язык интерфейса по умолчанию для экранов до входа, системных писем и новых пользователей. Каждый пользователь может выбрать свой язык в профиле.", - "label": "Язык по умолчанию", - "hint": "Используется, когда пользователь не выбрал собственный язык.", - "save": "Сохранить", - "saving": "Сохранение…", - "saved": "Язык платформы обновлён", - "loadError": "Не удалось загрузить настройку языка", - "saveError": "Не удалось сохранить настройку языка" - }, - "branding": { - "title": "Брендинг", - "subtitle": "Оформите UTMStack под фирменный стиль вашей организации — он применяется везде: на экране входа, в боковой панели, письмах и отчётах.", - "enterpriseRequired": "Брендинг под вашим именем — функция Enterprise.", - "manageLicense": "Управление лицензией", - "enable": { - "title": "Брендинг под вашим именем", - "description": "Замените бренд UTMStack своим во всей платформе.", - "label": "Включить брендинг под вашим именем" - }, - "identity": { - "title": "Идентичность", - "productName": "Название продукта", - "productNameHint": "Отображается в заголовке окна, боковой панели и письмах.", - "accent": "Акцентный цвет", - "accentHint": "Основной цвет для кнопок, ссылок и активных состояний.", - "custom": "Свой цвет" - }, - "logos": { - "title": "Логотипы", - "hint": "PNG, SVG, WEBP, JPG или ICO. До 5 МБ.", - "logo": "Логотип (светлый)", - "logoDark": "Логотип (тёмный)", - "favicon": "Фавикон" - }, - "reports": { - "title": "Ресурсы отчётов", - "hint": "Встраиваются в создаваемые PDF-отчёты.", - "reportLogo": "Логотип отчёта", - "reportCover": "Обложка отчёта" - }, - "asset": { - "upload": "Загрузить", - "replace": "Заменить" - }, - "save": "Сохранить изменения", - "saving": "Сохранение…", - "saved": "Брендинг обновлён", - "saveError": "Не удалось сохранить брендинг", - "uploaded": "Изображение загружено", - "uploadError": "Не удалось загрузить изображение", - "loadError": "Не удалось загрузить брендинг", - "enterprise": { - "title": "Белая метка — функция Enterprise", - "body": "Замените название продукта, логотип и обложку отчётов на свои, чтобы панель и всё, что она создаёт, несли ваш бренд, а не UTMStack.", - "upgrade": "Перейти на Enterprise" - }, - "restore": "Восстановить значения UTMStack", - "restored": "Оформление восстановлено к значениям UTMStack" - }, - "emailConfig": { - "title": "Настройка электронной почты", - "subtitle": "SMTP-сервер для отправки уведомлений об угрозах, отчётов и писем по учётным записям.", - "server": { - "title": "SMTP-сервер", - "host": "Хост", - "hostHint": "Имя хоста вашего SMTP-сервера.", - "port": "Порт", - "encryption": "Шифрование", - "username": "Имя пользователя", - "password": "Пароль", - "passwordSetHint": "Пароль сохранён. Оставьте поле пустым, чтобы сохранить его, или введите новый, чтобы изменить." - }, - "encryptionOpt": { - "TLS": "TLS", - "SSL": "SSL", - "NONE": "Нет" - }, - "sender": { - "title": "Отправитель", - "from": "Адрес отправителя", - "fromHint": "Адрес, с которого отправляются письма.", - "organization": "Название организации", - "organizationHint": "Отображается в письмах об угрозах и инцидентах.", - "baseUrl": "Базовый URL", - "baseUrlHint": "Публичный URL этого экземпляра, используется для ссылок в письмах." - }, - "test": { - "button": "Отправить тест", - "sending": "Отправка…", - "sentTo": "Тестовое письмо будет отправлено на {{email}}.", - "success": "Тестовое письмо отправлено на {{email}}", - "fail": "Не удалось отправить тестовое письмо", - "fromRequired": "Укажите адрес отправителя перед тестированием" - }, - "save": "Сохранить изменения", - "saving": "Сохранение…", - "saved": "Настройка электронной почты сохранена", - "saveError": "Не удалось сохранить настройку", - "loadError": "Не удалось загрузить настройку", - "recipients": { - "alertsTitle": "Получатели оповещений", - "incidentsTitle": "Получатели инцидентов", - "to": "Кому", - "cc": "Копия", - "alertsHelper": "Адреса, на которые приходят новые оповещения. Если оставить пустым, оповещения по почте не отправляются.", - "incidentsHelper": "Адреса, на которые приходит уведомление о создании инцидента. Если оставить пустым, уведомления по почте не отправляются.", - "add": "Добавить" - } - }, - "dateFormat": { - "title": "Дата и время", - "subtitle": "Как отображаются метки времени на платформе. Журналы всегда хранятся в UTC.", - "timezone": { - "title": "Часовой пояс", - "hint": "Метки времени показаны в этом часовом поясе. Сохранённые данные остаются в UTC.", - "system": "По умолчанию из браузера", - "now": "Сейчас: {{value}}" - }, - "format": { - "title": "Формат даты", - "hint": "Стиль отображения дат и времени." - }, - "styles": { - "short": "Короткий", - "medium": "Средний", - "long": "Длинный", - "full": "Полный" - }, - "save": "Сохранить изменения", - "saving": "Сохранение…", - "saved": "Настройки даты сохранены", - "saveError": "Не удалось сохранить настройки", - "loadError": "Не удалось загрузить настройки" - }, - "adversaries": { - "title": "Обзор противников", - "subtitle": "Каждый IP, хост или пользователь, замеченный в атаках на вашу среду, с их техниками и целями.", - "countChip": "Противников: {{count}}", - "refresh": "Обновить", - "search": "Поиск по IP, хосту, пользователю, стране, ASO…", - "empty": "Нет подходящих противников.", - "loadError": "Не удалось загрузить противников.", - "retry": "Повторить", - "views": { - "all": "Все", - "high": "Высокая серьёзность", - "ip": "IP-адреса", - "host": "Хосты", - "user": "Пользователи" - }, - "threat": { - "critical": "Критический", - "high": "Высокий", - "medium": "Средний", - "low": "Низкий" - }, - "kind": { - "ip": "IP", - "host": "Хост", - "user": "Пользователь" - }, - "layout": { - "list": "Список", - "cards": "Карточки" - }, - "overview": { - "title": "Активность противников · за последние 24 часа", - "high": "высокая серьёзность", - "countries": "страны", - "alerts": "оповещения", - "ago24": "24 ч назад", - "ago12": "12 ч назад", - "now": "сейчас" - }, - "col": { - "adversary": "Противник", - "threat": "Угроза", - "alerts": "Оповещения", - "targets": "Цели", - "lastSeen": "Последний раз", - "victims": "Жертвы" - }, - "card": { - "alerts": "Оповещения", - "techniques": "Техники", - "targets": "Цели" - }, - "tabs": { - "profile": "Профиль", - "techniques": "Техники", - "targets": "Цели", - "alerts": "Оповещения" - }, - "drawer": { - "activity": "Активность за 24 часа", - "identification": "Идентификация", - "kindLabel": "Тип", - "identifier": "Идентификатор", - "firstSeen": "Впервые замечен", - "lastSeen": "Последний раз", - "geolocation": "Геолокация", - "country": "Страна", - "city": "Город", - "topTechniques": "Основные техники", - "noTechniques": "Техники не зафиксированы.", - "targets": "Цели", - "noTargets": "Цели не зафиксированы.", - "recentAlerts": "Недавние оповещения", - "noAlerts": "Нет оповещений.", - "echoes": "{{count}} повторов" - }, - "relative": { - "justNow": "только что", - "minutesAgo": "{{count}} мин назад", - "hoursAgo": "{{count}} ч назад", - "daysAgo": "{{count}} дн назад" - }, - "field": { - "ip": "IP", - "host": "Хост", - "user": "Пользователь", - "port": "Порт", - "domain": "Домен", - "mac": "MAC", - "country": "Страна", - "city": "Город", - "asn": "ASN", - "aso": "ASO" - } - }, - "socAi": { - "title": "Настройка SOC-AI", - "subtitle": "Настройте ИИ-агента, который сортирует оповещения и обеспечивает работу операционного ассистента.", - "section": { - "connection": "Модель и подключение", - "auth": "Аутентификация", - "behavior": "Поведение при сортировке оповещений", - "advanced": "Расширенные" - }, - "usage": { - "title": "Использование", - "chat": "Запросы чата (сегодня)", - "unavailable": "Данные об использовании пока недоступны.", - "resetsIn": "Сброс через {{time}}" - }, - "provider": { - "label": "Поставщик", - "hint": "Определяет формат обмена. Всё, кроме Anthropic, использует API, совместимый с OpenAI." - }, - "model": { - "label": "Модель", - "hint": "Идентификатор модели, предоставляемый поставщиком.", - "customOption": "Своя модель…", - "customPlaceholder": "Введите идентификатор модели" - }, - "url": { - "label": "URL API", - "hint": "Оставьте пустым, чтобы использовать конечную точку поставщика по умолчанию." - }, - "apiKey": { - "label": "Ключ API", - "hint": "Учётные данные, отправляемые поставщику.", - "setHint": "Ключ сохранён. Оставьте пустым, чтобы сохранить его." - }, - "authType": { - "label": "Тип аутентификации", - "hint": "Как учётные данные отправляются на ваш шлюз.", - "options": { - "apiKey": "API-ключ", - "bearer": "Bearer", - "customHeaders": "Пользовательские заголовки", - "none": "Нет" - } - }, - "authHeaderName": { - "label": "Имя заголовка аутентификации", - "hint": "Заголовок, несущий ключ (например, api-key для Azure)." - }, - "authToken": { - "label": "Bearer-токен", - "hint": "Учётные данные, отправляемые провайдеру.", - "setHint": "Токен сохранён. Оставьте пустым, чтобы сохранить его." - }, - "customHeaders": { - "label": "Пользовательские заголовки", - "hint": "Дополнительные заголовки, отправляемые с каждым запросом. Значения шифруются; «*****» сохраняет хранимое значение.", - "keyPlaceholder": "Имя заголовка", - "valuePlaceholder": "Значение", - "addRow": "Добавить заголовок", - "remove": "Удалить заголовок" - }, - "maxTokens": { - "label": "Макс. токенов", - "hint": "Максимальное число токенов на один ответ LLM." - }, - "maxToolIterations": { - "label": "Макс. итераций инструментов", - "hint": "Ограничение на цикл агента план -> инструмент -> наблюдение." - }, - "autoAnalyze": { - "label": "Автоанализ оповещений", - "hint": "Сортировать входящие оповещения в реальном времени." - }, - "allowIncidents": { - "label": "Разрешить управление инцидентами", - "hint": "Агент сортировки может создавать или обновлять инциденты, если считает, что оповещение этого требует." - }, - "changeAlertStatus": { - "label": "Изменять статус оповещения", - "hint": "Разрешить агенту устанавливать статус оповещения во время сортировки." - }, - "automaticIncidentCreation": { - "label": "Создавать инциденты", - "hint": "Разрешить агенту открывать инциденты на основе отсортированных оповещений." - }, - "allowedWriteTools": { - "label": "Разрешённые инструменты записи", - "hint": "По одному имени MCP-инструмента на строку, которое может использовать агент сортировки (например, alerts.update_status). Заметки разрешены всегда." - }, - "save": "Сохранить настройку", - "saving": "Проверка и сохранение...", - "saved": "Настройка SOC-AI сохранена", - "saveError": "Не удалось сохранить настройку", - "loadError": "Не удалось загрузить настройку", - "modelRequired": "Необходимо указать модель", - "applyTags": { - "label": "Применять теги", - "hint": "Разрешить агенту тегировать оповещения во время сортировки." - }, - "note": { - "azure": "Вставьте полную конечную точку развёртывания Azure в качестве URL; модель — это имя вашего развёртывания. Аутентификация использует заголовок api-key.", - "ollama": "Укажите URL вашего хоста Ollama. Для локального экземпляра ключ API не требуется.", - "custom": "Любая конечная точка, совместимая с OpenAI. Укажите URL, аутентификацию и любые дополнительные заголовки, необходимые вашему шлюзу.", - "threatwinds": "Автоматически использует вашу лицензию UTMStack — API-ключ не нужен. Оплата через вашу подписку ThreatWinds." - }, - "chat": { - "title": "SOC-ассистент", - "dashboardCreateTitle": "Конструктор панелей", - "empty": "Спросите что угодно о ваших оповещениях, обнаружениях или консоли — я могу провести расследование и действовать в SIEM.", - "tryPrefix": "Попробуйте", - "suggestion": "сколько открытых оповещений, сгруппированных по противнику?", - "placeholder": "Задайте вопрос…", - "ask": "Спросить", - "send": "Отправить", - "collapse": "Свернуть", - "expand": "Развернуть", - "clear": "Очистить переписку", - "close": "Закрыть", - "copy": "Копировать", - "copied": "Скопировано", - "errorGeneric": "Что-то пошло не так.", - "errorUnreachable": "Не удалось связаться с ассистентом.", - "compacting": "Сжатие контекста…", - "dashboardEditTitle": "Редактор панелей", - "editingDashboard": "Редактирование: {{name}}", - "soarEditTitle": "Редактор потоков SOAR", - "soarCreateTitle": "Создать поток SOAR", - "editingFlow": "Редактирование потока: {{name}}" - }, - "focus": { - "alert": "Оповещение", - "incident": "Инцидент", - "remove": "Больше не делиться с ассистентом" - }, - "inheritance": { - "inherited": "Используются настройки экземпляра по умолчанию. Сохранение создаст собственные настройки этого арендатора.", - "own": "У этого арендатора собственные настройки.", - "revert": "Вернуться к настройкам экземпляра", - "reverting": "Возврат…", - "reverted": "Теперь используются настройки экземпляра" - }, - "allowance": { - "title": "Расход ИИ сегодня", - "ofLimit": "из {{limit}} запросов", - "denied": "запросов — ИИ недоступен этому арендатору", - "hint": "Задаётся оператором экземпляра. Сбрасывается в полночь UTC." - } - }, - "taggingRules": { - "title": "Правила тегирования", - "subtitle": "Автоматически тегировать оповещения, соответствующие условиям.", - "new": "Новое правило", - "refresh": "Обновить", - "empty": "Правил тегирования пока нет.", - "loadError": "Не удалось загрузить правила тегирования.", - "retry": "Повторить", - "deleteConfirm": "Удалить правило «{{name}}»? Будущие оповещения, соответствующие его условиям, перестанут тегироваться.", - "toolbar": { - "search": "Поиск по названию правила…", - "allTags": "Все теги" - }, - "table": { - "rule": "Правило", - "tags": "Теги", - "conditions": "Условия", - "modifiedBy": "Кем изменено", - "modifiedDate": "Изменено" - }, - "drawer": { - "createTitle": "Новое правило тегирования", - "edit": "Изменить", - "delete": "Удалить", - "save": "Сохранить", - "create": "Создать", - "cancel": "Отмена" - }, - "form": { - "basics": "Основное", - "name": "Название правила", - "namePlaceholder": "например, Внутренний перебор SSH", - "description": "Описание", - "descriptionPlaceholder": "Зачем нужно это правило и что оно тегирует.", - "tags": "Применяемые теги", - "noTags": "Теги не выбраны.", - "addTag": "Добавить тег", - "removeTag": "Удалить", - "noCatalog": "В каталоге пока нет тегов.", - "createTag": "Создать тег", - "newTagName": "Название нового тега", - "conditions": "Условия (должны совпасть ВСЕ)", - "noConditions": "Требуется хотя бы одно условие.", - "addCondition": "Добавить условие", - "removeCondition": "Удалить условие", - "valuePlaceholder": "Значение", - "valueListPlaceholder": "Значения через запятую", - "incomplete": "Заполните название правила, описание, хотя бы один тег и завершите каждое условие." - }, - "view": { - "description": "Описание", - "tags": "Теги", - "conditions": "Условия", - "audit": "Аудит", - "createdBy": "Кем создано", - "createdDate": "Создано", - "modifiedBy": "Кем изменено", - "modifiedDate": "Изменено" - }, - "toast": { - "created": "Правило «{{name}}» создано.", - "updated": "Правило «{{name}}» обновлено.", - "deleted": "Правило «{{name}}» удалено.", - "createError": "Не удалось создать правило.", - "updateError": "Не удалось обновить правило.", - "deleteError": "Не удалось удалить правило." - }, - "deleteTitle": "Удалить правило тегирования" - }, - "threatIntel": { - "header": { - "matchedInEnv": "совпадения в вашей среде", - "export": "Экспортировать IOCs", - "exporting": "Экспортирование…", - "noInstanceIocs": "Нет индикаторов среды — показаны общие данные", - "noInstanceIocsHint": "В ваших оповещениях не обнаружено индикаторов — отображаются общие данные из фидов." - }, - "overview": { - "title": "Совпадения IOC", - "totalIndicators": "всего индикаторов", - "families": { - "ip": "IP", - "url": "URL", - "domain": "Домен", - "signatures": "Сигнатуры" - } - }, - "notConfigured": { - "title": "Threat Intelligence не настроен", - "body": "Свяжитесь с администратором для подключения экземпляра Cyber Mantra / ThreatWinds к этой среде." - }, - "lookup": { - "title": "Поиск любого индикатора", - "placeholder": "Вставьте IP, доменное имя, хеш, URL или CVE — мы проверим feed и вашу среду", - "button": "Поиск", - "busy": "Поиск…" - }, - "tabs": { - "iocs": "IOCs", - "actors": "Угрозы", - "feeds": "Feeds", - "analyst": "ИИ-аналитик" - }, - "toolbar": { - "searchPlaceholders": { - "iocs": "Поиск по значению IOC, тегу, источнику…", - "actors": "Поиск по актёрам, алиасам, техникам…", - "feeds": "Поиск по feeds…" - }, - "last24h": "Последние 24 часа", - "filters": "Фильтры", - "refresh": "Обновить" - }, - "iocs": { - "table": { - "type": "Тип", - "indicator": "Индикатор", - "reputation": "Репутация", - "tags": "Теги", - "lastSeen": "Последний просмотр" - }, - "empty": "Нет совпадений IOC.", - "loadingMore": "Загрузка…", - "loadedProgress": "Загружено {{loaded}} из {{total}}. Прокрутите для других.", - "endOfResults": "Конец результатов ({{loaded}} из {{total}})." - }, - "drawer": { - "loading": "Загрузка…", - "accuracy": "Точность:", - "actions": { - "block": "Заблокировать на периметре", - "viewEvents": "Просмотреть совпадающие события", - "externalLookup": "Внешний поиск", - "trackCampaign": "Отслеживать кампанию", - "viewIocs": "Просмотреть совпадающие IOCs", - "mitre": "MITRE ATT&CK" - }, - "sections": { - "timeline": "Временная шкала", - "networkOrigin": "Сеть / происхождение", - "associationsWithCount": "Ассоциации ({{count}})", - "geolocationsWithCount": "Геолокации ({{count}})", - "about": "О программе", - "activity": "Активность" - }, - "fields": { - "firstSeen": "Впервые обнаружено", - "lastSeen": "Последний просмотр", - "country": "Страна", - "city": "Город", - "aso": "ASO", - "asn": "ASN", - "reputation": "Репутация", - "accuracy": "Точность", - "current": "Текущее", - "best": "Лучшее", - "worst": "Худшее" - }, - "aiBrief": "Резюме ИИ", - "noDescription": "Описание не доступно для этого индикатора.", - "lastObserved": "Последний просмотр {{when}}." - }, - "actors": { - "empty": "Угрозы не найдены." - }, - "feeds": { - "empty": "Нет настроенных feeds.", - "table": { - "name": "Feed", - "type": "Тип", - "accuracy": "Точность", - "header": "Источники", - "format": "Формат" - }, - "download": "Скачать источник", - "checksum": "Контрольная сумма" - }, - "entityTypes": { - "ip": "IP", - "hostname": "Хост", - "domain": "Доменное имя", - "url": "URL", - "hash": "Hash", - "cve": "CVE", - "threat": "Угроза", - "entity": "Сущность" - }, - "reputation": { - "alarming": "Тревожная", - "suspicious": "Подозрительная", - "indefinable": "Неопределённая", - "fair": "Приемлемая", - "trustworthy": "Надёжная" - }, - "feedAccuracy": { - "level1": "Уровень 1", - "level2": "Уровень 2", - "level3": "Уровень 3" - }, - "triage": { - "title": "Triage", - "subtitle": "Paste indicators, get verdicts", - "input": "Indicators", - "placeholder": "Paste IPs, domains, URLs or hashes — one per line, or comma separated.\nDefanged values (1.2.3[.]4, hxxp://) are accepted.", - "run": "Triage", - "stop": "Stop", - "reset": "Clear", - "parsed": "{{count}} unique indicators", - "capped": "Capped at {{max}} per run.", - "progress": "{{done}} of {{total}}", - "empty": "Paste indicators above to begin.", - "indicator": "Indicator", - "type": "Type", - "verdict": "Verdict", - "reputation": "Rep", - "accuracy": "Acc", - "tags": "Tags", - "lastSeen": "Last seen", - "exportCsv": "Export CSV", - "exportStix": "Export STIX", - "stixNote": "STIX export includes malicious and suspicious rows only.", - "open": "Open", - "notConfigured": "Threat intelligence is not configured — triage needs an upstream ThreatWinds instance.", - "summary": "Summary", - "v.malicious": "Malicious", - "v.suspicious": "Suspicious", - "v.benign": "Benign", - "v.unknown": "Unknown", - "v.notFound": "Not found", - "v.invalid": "Unrecognised" - }, - "report": { - "title": "Сообщение", - "subtitle": "Опубликовать индикатор в графе ThreatWinds", - "submit": "Отправить индикатор", - "submitting": "Отправка…", - "error": { - "generic": "Не удалось отправить индикатор. Попробуйте ещё раз." - }, - "value": { - "label": "Индикатор", - "placeholder": "IP, домен, URL, хеш или e-mail" - }, - "type": { - "label": "Тип", - "placeholder": "Определяется из значения", - "inferred": "Определён: {{type}}", - "inferenceFailed": "Не удалось определить тип по этому значению. Выберите его из списка или введите.", - "unknown": "«{{type}}» — не тип сущности. Выберите из списка." - }, - "tags": { - "label": "Метки", - "placeholder": "phishing, кража-учётных-данных" - }, - "description": { - "label": "Заметки" - }, - "reputation": { - "legend": "Репутация", - "hint": "Оставьте пустым, если вы не приняли решения.", - "alarming": "Опасный", - "worrying": "Тревожный", - "concerning": "Подозрительный", - "indefinable": "Неопределённый", - "adequate": "Приемлемый", - "good": "Хороший", - "exceptional": "Отличный" - }, - "associations": { - "legend": "Связанные индикаторы", - "add": "Добавить связанный индикатор", - "remove": "Удалить", - "valuePlaceholder": "Связанное значение", - "typePlaceholder": "Тип (необязательно)", - "modeLabel": "Связь", - "mode": { - "association": "Связан с", - "aggregation": "Часть" - }, - "visibilityConflict": "Не имеет общей группы видимости с индикатором выше. Всё сообщение будет отклонено." - }, - "attributes": { - "legend": "Детали", - "hint": "Необязательно. Пустые поля не отправляются.", - "invalidHex": "Ожидается {{length}} шестнадцатеричных символов.", - "invalidHexAny": "Только шестнадцатеричные символы.", - "invalidNumber": "Ожидается число." - }, - "correlate": { - "legend": "Скоррелировать", - "hint": "Каждый отмеченный атрибут публикуется как отдельная сущность, связанная с этой.", - "count_one": "Создаёт {{count}} связанную сущность.", - "count_other": "Создаёт {{count}} связанных сущностей." - }, - "scan": { - "notice": "Также ставит сканирование цели в очередь." - }, - "receipt": { - "title": "Отправлено", - "noVerdict": "Решение не принято", - "skipped": "Не отправлено, тип не удалось определить", - "pending": "Ожидание появления индикатора в корпусе…", - "live": "Присутствует в корпусе — посмотреть сущность", - "processing": "Ещё обрабатывается. Появится, когда загрузка догонит очередь.", - "another": "Отправить ещё" - }, - "visibility": { - "legend": "Видимо для" - }, - "example": "Попробовать пример" - } - }, - "playground": { - "titleFilter": "Тест конвейера", - "titleRule": "Тест правила", - "noDataTypes": "У этого конвейера пока нет назначенных типов данных — добавьте один, чтобы протестировать.", - "dataTypeLabel": "Тип данных", - "dataTypePlaceholder": "Нет доступных типов данных", - "dataTypeSingleHint": "У этого конвейера только один тип данных — добавьте больше, чтобы выбирать.", - "rawLogLabel": "Исходный лог", - "rawLogPlaceholder": "Вставьте пример строки лога…", - "rawLogCounter": "{{chars}} симв. · {{kb}} КБ", - "rawLogTooLarge": "Этот лог превышает лимит 1 МБ — сократите его перед запуском теста.", - "run": { - "label": "Запустить", - "running": "Тестирование…", - "waitHint": "Это может занять до 15 секунд, пока конвейер обрабатывает лог." - }, - "errors": { - "busy": "Playground сейчас выполняет другой тест — попробуйте ещё раз чуть позже.", - "timeout": "Время теста истекло — обычно это значит, что выбранный тип данных не соответствует формату лога.", - "validation": "Некорректный запрос — проверьте исходный лог и содержимое конвейера.", - "server": "Playground не смог завершить тест — попробуйте снова." - }, - "notices": { - "geo": "Плагин геолокации недоступен в этой упрощённой версии теста фильтров и правил.", - "correlation": "Правила, обращающиеся к предыдущим событиям через операторы afterEvent или correlation, требуют наличия соответствующих событий в системе, чтобы тестируемое оповещение сработало." - }, - "result": { - "label": "Обработанный результат", - "empty": "Запустите тест, чтобы увидеть здесь обработанное событие.", - "loading": "Ожидание обработанного события…", - "tabs": { - "fields": "Поля", - "json": "JSON" - }, - "fieldsCount_one": "{{count}} поле", - "fieldsCount_other": "{{count}} полей", - "copy": "Копировать", - "copied": "Скопировано", - "elapsed": "Обработано за {{time}}", - "elapsedHint": "Время от запуска до обработанного результата", - "searchPlaceholder": "Поиск полей…", - "noMatch": "Ни одно поле не соответствует запросу." - }, - "alerts": { - "label": "Оповещения", - "empty": "Запустите тест, чтобы увидеть здесь появившиеся оповещения.", - "none": "Оповещения не сработали.", - "count_one": "{{count}} оповещение", - "count_other": "{{count}} оповещений" - }, - "title": "Test pipeline" - }, - "tenants": { - "title": "Арендаторы", - "new": "Новый арендатор", - "subtitle": "Каждый клиент на этом экземпляре: что у него есть и что он разрешает вам видеть.", - "searchPlaceholder": "Поиск по имени или домену…", - "loading": "Загрузка арендаторов…", - "loadFailed": "Не удалось загрузить арендаторов.", - "retry": "Повторить", - "none": "Арендаторов пока нет.", - "noSearchMatch": "Совпадений не найдено.", - "cancel": "Отмена", - "saving": "Сохранение…", - "chips": { - "total": "арендаторов", - "active": "активных", - "readable": "с доступом" - }, - "status": { - "ACTIVE": "Активен", - "SUSPENDED": "Приостановлен", - "TERMINATED": "Закрыт" - }, - "support": { - "NONE": "Нет доступа", - "READ": "Доступ на чтение", - "FULL": "Полный доступ", - "hint": "Выдаётся арендатором, а не вами. Изменить это может только его администратор." - }, - "card": { - "edit": "Изменить", - "activate": "Активировать", - "deactivate": "Деактивировать", - "deletePermanent": "Удалить безвозвратно", - "noAccess": "Этот арендатор не предоставил вам доступ.", - "loadingStats": "Чтение…", - "enter": "Войти" - }, - "stats": { - "users": "Пользователи", - "datasources": "Источники", - "openAlerts": "Открытые оповещения", - "ai": "ИИ сегодня", - "noLimit": "без лимита" - }, - "fields": { - "name": "Название", - "domain": "Домен", - "domainHint": "По какому адресу доступен арендатор. Любой запрос на этот хост попадает в его данные.", - "adminEmail": "Почта администратора", - "adminEmailHint": "Он получит приглашение, чтобы задать собственный пароль.", - "status": "Статус", - "suspendedWarning": "Приостановленный арендатор не сможет войти. Его данные сохраняются.", - "aiLimit": "Лимит запросов к ИИ", - "aiLimitHint": "Операционный лимит в сутки. Без лимита расход идёт по лицензии экземпляра.", - "aiLimitToggle": "Ограничить этого арендатора" - }, - "create": { - "title": "Новый арендатор", - "subtitle": "Создаёт арендатора и приглашает его первого администратора.", - "submit": "Создать арендатора" - }, - "edit": { - "title": "Изменение арендатора", - "subtitle": "Доступа поддержки здесь нет: его выдаёт только сам арендатор.", - "submit": "Сохранить" - }, - "terminate": { - "title": "Деактивировать этого арендатора?", - "body": "Никто из {{name}} не сможет войти. Данные сохраняются, так что это обратимо, но клиент отключается сейчас.", - "confirmLabel": "Введите {{name}} для подтверждения", - "submit": "Деактивировать" - }, - "reactivate": { - "title": "Активировать этого арендатора?", - "body": "{{name}} снова сможет войти. Сохранённые данные восстанавливаются как есть.", - "submit": "Активировать" - }, - "deletePermanent": { - "title": "Удалить этого арендатора навсегда?", - "body": "Все следы {{name}} — пользователи, источники данных, дашборды, оповещения, интеграции — будут стёрты. Это нельзя отменить.", - "confirmLabel": "Введите {{name}} для подтверждения", - "submit": "Удалить навсегда" - }, - "toast": { - "created": "Арендатор создан", - "updated": "Арендатор обновлён", - "terminated": "Арендатор закрыт", - "reactivated": "Арендатор восстановлен", - "permanentlyDeleted": "Арендатор удалён безвозвратно", - "domainInUse": "Этот домен уже занят", - "noPermission": "У вас нет прав на это действие", - "notFound": "Арендатор не найден", - "invalidRequest": "Некорректный запрос", - "operationFailed": "Операция не выполнена" - }, - "switcher": { - "aria": "Switch tenant", - "self": "Default tenant", - "create": "Create tenant" - } - }, - "supportAccess": { - "title": "Доступ поддержки", - "intro": "Тот, кто обслуживает этот экземпляр, не может заглянуть в ваши данные без вашего разрешения. По умолчанию здесь не выдано ничего, и вы можете отозвать доступ в любой момент.", - "loading": "Загрузка…", - "loadFailed": "Не удалось прочитать текущую настройку.", - "retry": "Повторить", - "currentBadge": "сейчас", - "save": "Сохранить", - "saving": "Сохранение…", - "levels": { - "NONE": { - "name": "Нет доступа", - "desc": "Оператор видит только то, что ваш арендатор существует. Любые запросы к вашим данным отклоняются." - }, - "READ": { - "name": "Только чтение", - "desc": "Оператор может смотреть ваши оповещения, журналы и настройки, чтобы помочь. Изменить он ничего не может: любая запись отклоняется, какая бы роль у него ни была." - }, - "FULL": { - "name": "Полный доступ", - "desc": "Оператор может действовать в вашем арендаторе как администратор: менять настройки, пользователей и сценарии реагирования." - } - }, - "fullWarning": "Полный доступ позволяет менять всё от вашего имени. Выдавайте его на время работ и возвращайте обратно после.", - "revokeNote": "Все действия оператора здесь попадают в ваш журнал аудита.", - "toast": { - "granted": "Доступ поддержки обновлён", - "revoked": "Доступ поддержки отозван", - "forbidden": "Менять это может только администратор этого арендатора", - "invalid": "Некорректный запрос", - "failed": "Не удалось сохранить изменение" - } - }, - "supportSession": { - "inside": "Вы работаете внутри {{name}}", - "readOnly": "только чтение — запись отклоняется", - "full": "полный доступ — изменения здесь настоящие", - "leave": "Выйти" - }, - "platformBroadcast": { - "button": "Применить ко всем арендаторам", - "action": { - "create": "Массовое создание: {{resource}}", - "update": "Массовое обновление: {{resource}}", - "delete": "Массовое удаление: {{resource}}", - "toggle": "Массовое переключение: {{resource}}", - "enable": "Массовое включение: {{resource}}", - "activate": "Массовая активация: {{resource}}", - "test": "Массовый тест: {{resource}}", - "upload": "Массовая загрузка ресурса {{resource}}" - }, - "resource": { - "pipeline": "конвейер", - "correlationRule": "правило корреляции", - "soarFlow": "SOAR-поток", - "framework": "фреймворк", - "control": "контроль", - "smtp": "SMTP", - "idp": "провайдер идентификации", - "branding": "брендинг" + "dateFormat": { + "title": "Дата и время", + "subtitle": "Как отображаются метки времени на платформе. Журналы всегда хранятся в UTC.", + "timezone": { + "title": "Часовой пояс", + "hint": "Метки времени показаны в этом часовом поясе. Сохранённые данные остаются в UTC.", + "system": "По умолчанию из браузера", + "now": "Сейчас: {{value}}" + }, + "format": { + "title": "Формат даты", + "hint": "Стиль отображения дат и времени." + }, + "styles": { + "short": "Короткий", + "medium": "Средний", + "long": "Длинный", + "full": "Полный" + }, + "save": "Сохранить изменения", + "saving": "Сохранение…", + "saved": "Настройки даты сохранены", + "saveError": "Не удалось сохранить настройки", + "loadError": "Не удалось загрузить настройки" + }, + "adversaries": { + "title": "Обзор противников", + "subtitle": "Каждый IP, хост или пользователь, замеченный в атаках на вашу среду, с их техниками и целями.", + "countChip": "Противников: {{count}}", + "refresh": "Обновить", + "search": "Поиск по IP, хосту, пользователю, стране, ASO…", + "empty": "Нет подходящих противников.", + "loadError": "Не удалось загрузить противников.", + "retry": "Повторить", + "views": { + "all": "Все", + "high": "Высокая серьёзность", + "ip": "IP-адреса", + "host": "Хосты", + "user": "Пользователи" + }, + "threat": { + "critical": "Критический", + "high": "Высокий", + "medium": "Средний", + "low": "Низкий" + }, + "kind": { + "ip": "IP", + "host": "Хост", + "user": "Пользователь" + }, + "layout": { + "list": "Список", + "cards": "Карточки" + }, + "overview": { + "title": "Активность противников · за последние 24 часа", + "high": "высокая серьёзность", + "countries": "страны", + "alerts": "оповещения", + "ago24": "24 ч назад", + "ago12": "12 ч назад", + "now": "сейчас" + }, + "col": { + "adversary": "Противник", + "threat": "Угроза", + "alerts": "Оповещения", + "targets": "Цели", + "lastSeen": "Последний раз", + "victims": "Жертвы" + }, + "card": { + "alerts": "Оповещения", + "techniques": "Техники", + "targets": "Цели" + }, + "tabs": { + "profile": "Профиль", + "techniques": "Техники", + "targets": "Цели", + "alerts": "Оповещения" + }, + "drawer": { + "activity": "Активность за 24 часа", + "identification": "Идентификация", + "kindLabel": "Тип", + "identifier": "Идентификатор", + "firstSeen": "Впервые замечен", + "lastSeen": "Последний раз", + "geolocation": "Геолокация", + "country": "Страна", + "city": "Город", + "topTechniques": "Основные техники", + "noTechniques": "Техники не зафиксированы.", + "targets": "Цели", + "noTargets": "Цели не зафиксированы.", + "recentAlerts": "Недавние оповещения", + "noAlerts": "Нет оповещений.", + "echoes": "{{count}} повторов" + }, + "relative": { + "justNow": "только что", + "minutesAgo": "{{count}} мин назад", + "hoursAgo": "{{count}} ч назад", + "daysAgo": "{{count}} дн назад" + }, + "field": { + "ip": "IP", + "host": "Хост", + "user": "Пользователь", + "port": "Порт", + "domain": "Домен", + "mac": "MAC", + "country": "Страна", + "city": "Город", + "asn": "ASN", + "aso": "ASO" + } }, - "warning": { - "title": "Это действие будет выполнено для каждого выбранного арендатора.", - "body": "Ошибки по арендаторам сообщаются после выполнения и не откатываются." + "socAi": { + "title": "Настройка SOC-AI", + "subtitle": "Настройте ИИ-агента, который сортирует оповещения и обеспечивает работу операционного ассистента.", + "section": { + "connection": "Модель и подключение", + "auth": "Аутентификация", + "behavior": "Поведение при сортировке оповещений", + "advanced": "Расширенные" + }, + "usage": { + "title": "Использование", + "chat": "Запросы чата (сегодня)", + "unavailable": "Данные об использовании пока недоступны.", + "resetsIn": "Сброс через {{time}}" + }, + "provider": { + "label": "Поставщик", + "hint": "Определяет формат обмена. Всё, кроме Anthropic, использует API, совместимый с OpenAI." + }, + "model": { + "label": "Модель", + "hint": "Идентификатор модели, предоставляемый поставщиком.", + "customOption": "Своя модель…", + "customPlaceholder": "Введите идентификатор модели" + }, + "url": { + "label": "URL API", + "hint": "Оставьте пустым, чтобы использовать конечную точку поставщика по умолчанию." + }, + "apiKey": { + "label": "Ключ API", + "hint": "Учётные данные, отправляемые поставщику.", + "setHint": "Ключ сохранён. Оставьте пустым, чтобы сохранить его." + }, + "authType": { + "label": "Тип аутентификации", + "hint": "Как учётные данные отправляются на ваш шлюз.", + "options": { + "apiKey": "API-ключ", + "bearer": "Bearer", + "customHeaders": "Пользовательские заголовки", + "none": "Нет" + } + }, + "authHeaderName": { + "label": "Имя заголовка аутентификации", + "hint": "Заголовок, несущий ключ (например, api-key для Azure)." + }, + "authToken": { + "label": "Bearer-токен", + "hint": "Учётные данные, отправляемые провайдеру.", + "setHint": "Токен сохранён. Оставьте пустым, чтобы сохранить его." + }, + "customHeaders": { + "label": "Пользовательские заголовки", + "hint": "Дополнительные заголовки, отправляемые с каждым запросом. Значения шифруются; «*****» сохраняет хранимое значение.", + "keyPlaceholder": "Имя заголовка", + "valuePlaceholder": "Значение", + "addRow": "Добавить заголовок", + "remove": "Удалить заголовок" + }, + "maxTokens": { + "label": "Макс. токенов", + "hint": "Максимальное число токенов на один ответ LLM." + }, + "maxToolIterations": { + "label": "Макс. итераций инструментов", + "hint": "Ограничение на цикл агента план -> инструмент -> наблюдение." + }, + "autoAnalyze": { + "label": "Автоанализ оповещений", + "hint": "Сортировать входящие оповещения в реальном времени." + }, + "allowIncidents": { + "label": "Разрешить управление инцидентами", + "hint": "Агент сортировки может создавать или обновлять инциденты, если считает, что оповещение этого требует." + }, + "changeAlertStatus": { + "label": "Изменять статус оповещения", + "hint": "Разрешить агенту устанавливать статус оповещения во время сортировки." + }, + "automaticIncidentCreation": { + "label": "Создавать инциденты", + "hint": "Разрешить агенту открывать инциденты на основе отсортированных оповещений." + }, + "allowedWriteTools": { + "label": "Разрешённые инструменты записи", + "hint": "По одному имени MCP-инструмента на строку, которое может использовать агент сортировки (например, alerts.update_status). Заметки разрешены всегда." + }, + "save": "Сохранить настройку", + "saving": "Проверка и сохранение...", + "saved": "Настройка SOC-AI сохранена", + "saveError": "Не удалось сохранить настройку", + "loadError": "Не удалось загрузить настройку", + "modelRequired": "Необходимо указать модель", + "applyTags": { + "label": "Применять теги", + "hint": "Разрешить агенту тегировать оповещения во время сортировки." + }, + "note": { + "azure": "Вставьте полную конечную точку развёртывания Azure в качестве URL; модель — это имя вашего развёртывания. Аутентификация использует заголовок api-key.", + "ollama": "Укажите URL вашего хоста Ollama. Для локального экземпляра ключ API не требуется.", + "custom": "Любая конечная точка, совместимая с OpenAI. Укажите URL, аутентификацию и любые дополнительные заголовки, необходимые вашему шлюзу.", + "threatwinds": "Автоматически использует вашу лицензию UTMStack — API-ключ не нужен. Оплата через вашу подписку ThreatWinds." + }, + "chat": { + "title": "SOC-ассистент", + "dashboardCreateTitle": "Конструктор панелей", + "empty": "Спросите что угодно о ваших оповещениях, обнаружениях или консоли — я могу провести расследование и действовать в SIEM.", + "tryPrefix": "Попробуйте", + "suggestion": "сколько открытых оповещений, сгруппированных по противнику?", + "placeholder": "Задайте вопрос…", + "ask": "Спросить", + "send": "Отправить", + "collapse": "Свернуть", + "expand": "Развернуть", + "clear": "Очистить переписку", + "close": "Закрыть", + "copy": "Копировать", + "copied": "Скопировано", + "errorGeneric": "Что-то пошло не так.", + "errorUnreachable": "Не удалось связаться с ассистентом.", + "compacting": "Сжатие контекста…", + "dashboardEditTitle": "Редактор панелей", + "editingDashboard": "Редактирование: {{name}}", + "soarEditTitle": "Редактор потоков SOAR", + "soarCreateTitle": "Создать поток SOAR", + "editingFlow": "Редактирование потока: {{name}}" + }, + "focus": { + "alert": "Оповещение", + "incident": "Инцидент", + "remove": "Больше не делиться с ассистентом" + }, + "inheritance": { + "inherited": "Используются настройки экземпляра по умолчанию. Сохранение создаст собственные настройки этого арендатора.", + "own": "У этого арендатора собственные настройки.", + "revert": "Вернуться к настройкам экземпляра", + "reverting": "Возврат…", + "reverted": "Теперь используются настройки экземпляра" + }, + "allowance": { + "title": "Расход ИИ сегодня", + "ofLimit": "из {{limit}} запросов", + "denied": "запросов — ИИ недоступен этому арендатору", + "hint": "Задаётся оператором экземпляра. Сбрасывается в полночь UTC." + } }, - "allTenants": "Применить ко всем арендаторам", - "excludesDefault": "Арендатор платформы исключён из этого действия.", - "searchPlaceholder": "Поиск арендаторов…", - "loading": "Загрузка арендаторов…", - "empty": "Арендаторы не найдены.", - "targetCount": "Будет применено к {{count}} арендатор(ам).", - "platformTenant": "платформа", - "confirm": "Применить к {{count}} арендатор(ам)", - "result": { - "succeeded": "Успешно", - "noneSucceeded": "Ни один арендатор не завершился успешно.", - "failed": "Не удалось", - "noneFailed": "Ошибок нет." - } - }, - "tiAnalyst": { - "console": { - "subtitle": "Рабочее пространство аналитика", - "model": "Модель", - "resizeResults": "Изменить размер панели результатов", - "resizeHint": "Перетащите, чтобы изменить размер · двойной клик — сброс" + "taggingRules": { + "title": "Правила тегирования", + "subtitle": "Автоматически тегировать оповещения, соответствующие условиям.", + "new": "Новое правило", + "refresh": "Обновить", + "empty": "Правил тегирования пока нет.", + "loadError": "Не удалось загрузить правила тегирования.", + "retry": "Повторить", + "deleteConfirm": "Удалить правило «{{name}}»? Будущие оповещения, соответствующие его условиям, перестанут тегироваться.", + "toolbar": { + "search": "Поиск по названию правила…", + "allTags": "Все теги" + }, + "table": { + "rule": "Правило", + "tags": "Теги", + "conditions": "Условия", + "modifiedBy": "Кем изменено", + "modifiedDate": "Изменено" + }, + "drawer": { + "createTitle": "Новое правило тегирования", + "edit": "Изменить", + "delete": "Удалить", + "save": "Сохранить", + "create": "Создать", + "cancel": "Отмена" + }, + "form": { + "basics": "Основное", + "name": "Название правила", + "namePlaceholder": "например, Внутренний перебор SSH", + "description": "Описание", + "descriptionPlaceholder": "Зачем нужно это правило и что оно тегирует.", + "tags": "Применяемые теги", + "noTags": "Теги не выбраны.", + "addTag": "Добавить тег", + "removeTag": "Удалить", + "noCatalog": "В каталоге пока нет тегов.", + "createTag": "Создать тег", + "newTagName": "Название нового тега", + "conditions": "Условия (должны совпасть ВСЕ)", + "noConditions": "Требуется хотя бы одно условие.", + "addCondition": "Добавить условие", + "removeCondition": "Удалить условие", + "valuePlaceholder": "Значение", + "valueListPlaceholder": "Значения через запятую", + "incomplete": "Заполните название правила, описание, хотя бы один тег и завершите каждое условие." + }, + "view": { + "description": "Описание", + "tags": "Теги", + "conditions": "Условия", + "audit": "Аудит", + "createdBy": "Кем создано", + "createdDate": "Создано", + "modifiedBy": "Кем изменено", + "modifiedDate": "Изменено" + }, + "toast": { + "created": "Правило «{{name}}» создано.", + "updated": "Правило «{{name}}» обновлено.", + "deleted": "Правило «{{name}}» удалено.", + "createError": "Не удалось создать правило.", + "updateError": "Не удалось обновить правило.", + "deleteError": "Не удалось удалить правило." + }, + "deleteTitle": "Удалить правило тегирования" + }, + "threatIntel": { + "header": { + "matchedInEnv": "совпадения в вашей среде", + "export": "Экспортировать IOCs", + "exporting": "Экспортирование…", + "noInstanceIocs": "Нет индикаторов среды — показаны общие данные", + "noInstanceIocsHint": "В ваших оповещениях не обнаружено индикаторов — отображаются общие данные из фидов." + }, + "overview": { + "title": "Совпадения IOC", + "totalIndicators": "всего индикаторов", + "families": { + "ip": "IP", + "url": "URL", + "domain": "Домен", + "signatures": "Сигнатуры" + } + }, + "notConfigured": { + "title": "Threat Intelligence не настроен", + "body": "Свяжитесь с администратором для подключения экземпляра Cyber Mantra / ThreatWinds к этой среде." + }, + "lookup": { + "title": "Поиск любого индикатора", + "placeholder": "Вставьте IP, доменное имя, хеш, URL или CVE — мы проверим feed и вашу среду", + "button": "Поиск", + "busy": "Поиск…" + }, + "tabs": { + "iocs": "IOCs", + "actors": "Угрозы", + "feeds": "Feeds", + "analyst": "ИИ-аналитик" + }, + "toolbar": { + "searchPlaceholders": { + "iocs": "Поиск по значению IOC, тегу, источнику…", + "actors": "Поиск по актёрам, алиасам, техникам…", + "feeds": "Поиск по feeds…" + }, + "last24h": "Последние 24 часа", + "filters": "Фильтры", + "refresh": "Обновить" + }, + "iocs": { + "table": { + "type": "Тип", + "indicator": "Индикатор", + "reputation": "Репутация", + "tags": "Теги", + "lastSeen": "Последний просмотр" + }, + "empty": "Нет совпадений IOC.", + "loadingMore": "Загрузка…", + "loadedProgress": "Загружено {{loaded}} из {{total}}. Прокрутите для других.", + "endOfResults": "Конец результатов ({{loaded}} из {{total}})." + }, + "drawer": { + "loading": "Загрузка…", + "accuracy": "Точность:", + "actions": { + "block": "Заблокировать на периметре", + "viewEvents": "Просмотреть совпадающие события", + "externalLookup": "Внешний поиск", + "trackCampaign": "Отслеживать кампанию", + "viewIocs": "Просмотреть совпадающие IOCs", + "mitre": "MITRE ATT&CK" + }, + "sections": { + "timeline": "Временная шкала", + "networkOrigin": "Сеть / происхождение", + "associationsWithCount": "Ассоциации ({{count}})", + "geolocationsWithCount": "Геолокации ({{count}})", + "about": "О программе", + "activity": "Активность" + }, + "fields": { + "firstSeen": "Впервые обнаружено", + "lastSeen": "Последний просмотр", + "country": "Страна", + "city": "Город", + "aso": "ASO", + "asn": "ASN", + "reputation": "Репутация", + "accuracy": "Точность", + "current": "Текущее", + "best": "Лучшее", + "worst": "Худшее" + }, + "aiBrief": "Резюме ИИ", + "noDescription": "Описание не доступно для этого индикатора.", + "lastObserved": "Последний просмотр {{when}}." + }, + "actors": { + "empty": "Угрозы не найдены." + }, + "feeds": { + "empty": "Нет настроенных feeds.", + "table": { + "name": "Feed", + "type": "Тип", + "accuracy": "Точность", + "header": "Источники", + "format": "Формат" + }, + "download": "Скачать источник", + "checksum": "Контрольная сумма" + }, + "entityTypes": { + "ip": "IP", + "hostname": "Хост", + "domain": "Доменное имя", + "url": "URL", + "hash": "Hash", + "cve": "CVE", + "threat": "Угроза", + "entity": "Сущность" + }, + "reputation": { + "alarming": "Тревожная", + "suspicious": "Подозрительная", + "indefinable": "Неопределённая", + "fair": "Приемлемая", + "trustworthy": "Надёжная" + }, + "feedAccuracy": { + "level1": "Уровень 1", + "level2": "Уровень 2", + "level3": "Уровень 3" + }, + "triage": { + "title": "Triage", + "subtitle": "Paste indicators, get verdicts", + "input": "Indicators", + "placeholder": "Paste IPs, domains, URLs or hashes — one per line, or comma separated.\nDefanged values (1.2.3[.]4, hxxp://) are accepted.", + "run": "Triage", + "stop": "Stop", + "reset": "Clear", + "parsed": "{{count}} unique indicators", + "capped": "Capped at {{max}} per run.", + "progress": "{{done}} of {{total}}", + "empty": "Paste indicators above to begin.", + "indicator": "Indicator", + "type": "Type", + "verdict": "Verdict", + "reputation": "Rep", + "accuracy": "Acc", + "tags": "Tags", + "lastSeen": "Last seen", + "exportCsv": "Export CSV", + "exportStix": "Export STIX", + "stixNote": "STIX export includes malicious and suspicious rows only.", + "open": "Open", + "notConfigured": "Threat intelligence is not configured — triage needs an upstream ThreatWinds instance.", + "summary": "Summary", + "v.malicious": "Malicious", + "v.suspicious": "Suspicious", + "v.benign": "Benign", + "v.unknown": "Unknown", + "v.notFound": "Not found", + "v.invalid": "Unrecognised" + }, + "report": { + "title": "Сообщение", + "subtitle": "Опубликовать индикатор в графе ThreatWinds", + "submit": "Отправить индикатор", + "submitting": "Отправка…", + "error": { + "generic": "Не удалось отправить индикатор. Попробуйте ещё раз." + }, + "value": { + "label": "Индикатор", + "placeholder": "IP, домен, URL, хеш или e-mail" + }, + "type": { + "label": "Тип", + "placeholder": "Определяется из значения", + "inferred": "Определён: {{type}}", + "inferenceFailed": "Не удалось определить тип по этому значению. Выберите его из списка или введите.", + "unknown": "«{{type}}» — не тип сущности. Выберите из списка." + }, + "tags": { + "label": "Метки", + "placeholder": "phishing, кража-учётных-данных" + }, + "description": { + "label": "Заметки" + }, + "reputation": { + "legend": "Репутация", + "hint": "Оставьте пустым, если вы не приняли решения.", + "alarming": "Опасный", + "worrying": "Тревожный", + "concerning": "Подозрительный", + "indefinable": "Неопределённый", + "adequate": "Приемлемый", + "good": "Хороший", + "exceptional": "Отличный" + }, + "associations": { + "legend": "Связанные индикаторы", + "add": "Добавить связанный индикатор", + "remove": "Удалить", + "valuePlaceholder": "Связанное значение", + "typePlaceholder": "Тип (необязательно)", + "modeLabel": "Связь", + "mode": { + "association": "Связан с", + "aggregation": "Часть" + }, + "visibilityConflict": "Не имеет общей группы видимости с индикатором выше. Всё сообщение будет отклонено." + }, + "attributes": { + "legend": "Детали", + "hint": "Необязательно. Пустые поля не отправляются.", + "invalidHex": "Ожидается {{length}} шестнадцатеричных символов.", + "invalidHexAny": "Только шестнадцатеричные символы.", + "invalidNumber": "Ожидается число." + }, + "correlate": { + "legend": "Скоррелировать", + "hint": "Каждый отмеченный атрибут публикуется как отдельная сущность, связанная с этой.", + "count_one": "Создаёт {{count}} связанную сущность.", + "count_other": "Создаёт {{count}} связанных сущностей." + }, + "scan": { + "notice": "Также ставит сканирование цели в очередь." + }, + "receipt": { + "title": "Отправлено", + "noVerdict": "Решение не принято", + "skipped": "Не отправлено, тип не удалось определить", + "pending": "Ожидание появления индикатора в корпусе…", + "live": "Присутствует в корпусе — посмотреть сущность", + "processing": "Ещё обрабатывается. Появится, когда загрузка догонит очередь.", + "another": "Отправить ещё" + }, + "visibility": { + "legend": "Видимо для" + }, + "example": "Попробовать пример" + } }, - "conv": { - "title": "Диалоги", - "allConversations": "Все диалоги", - "empty": "Диалогов пока нет.", - "new": "Новый диалог", - "newTitle": "Название диалога", - "selectPrompt": "Выберите диалог или начните новый.", - "running": "выполняется", - "delete": "Удалить {{title}}", - "unread_one": "{{count}} непрочитанное сообщение", - "unread_other": "{{count}} непрочитанных сообщения", - "transcript": "Транскрипция диалога" + "playground": { + "titleFilter": "Тест конвейера", + "titleRule": "Тест правила", + "noDataTypes": "У этого конвейера пока нет назначенных типов данных — добавьте один, чтобы протестировать.", + "dataTypeLabel": "Тип данных", + "dataTypePlaceholder": "Нет доступных типов данных", + "dataTypeSingleHint": "У этого конвейера только один тип данных — добавьте больше, чтобы выбирать.", + "rawLogLabel": "Исходный лог", + "rawLogPlaceholder": "Вставьте пример строки лога…", + "rawLogCounter": "{{chars}} симв. · {{kb}} КБ", + "rawLogTooLarge": "Этот лог превышает лимит 1 МБ — сократите его перед запуском теста.", + "run": { + "label": "Запустить", + "running": "Тестирование…", + "waitHint": "Это может занять до 15 секунд, пока конвейер обрабатывает лог." + }, + "errors": { + "busy": "Playground сейчас выполняет другой тест — попробуйте ещё раз чуть позже.", + "timeout": "Время теста истекло — обычно это значит, что выбранный тип данных не соответствует формату лога.", + "validation": "Некорректный запрос — проверьте исходный лог и содержимое конвейера.", + "server": "Playground не смог завершить тест — попробуйте снова." + }, + "notices": { + "geo": "Плагин геолокации недоступен в этой упрощённой версии теста фильтров и правил.", + "correlation": "Правила, обращающиеся к предыдущим событиям через операторы afterEvent или correlation, требуют наличия соответствующих событий в системе, чтобы тестируемое оповещение сработало." + }, + "result": { + "label": "Обработанный результат", + "empty": "Запустите тест, чтобы увидеть здесь обработанное событие.", + "loading": "Ожидание обработанного события…", + "tabs": { + "fields": "Поля", + "json": "JSON" + }, + "fieldsCount_one": "{{count}} поле", + "fieldsCount_other": "{{count}} полей", + "copy": "Копировать", + "copied": "Скопировано", + "elapsed": "Обработано за {{time}}", + "elapsedHint": "Время от запуска до обработанного результата", + "searchPlaceholder": "Поиск полей…", + "noMatch": "Ни одно поле не соответствует запросу." + }, + "alerts": { + "label": "Оповещения", + "empty": "Запустите тест, чтобы увидеть здесь появившиеся оповещения.", + "none": "Оповещения не сработали.", + "count_one": "{{count}} оповещение", + "count_other": "{{count}} оповещений" + }, + "title": "Test pipeline" + }, + "tenants": { + "title": "Арендаторы", + "new": "Новый арендатор", + "subtitle": "Каждый клиент на этом экземпляре: что у него есть и что он разрешает вам видеть.", + "searchPlaceholder": "Поиск по имени или домену…", + "loading": "Загрузка арендаторов…", + "loadFailed": "Не удалось загрузить арендаторов.", + "retry": "Повторить", + "none": "Арендаторов пока нет.", + "noSearchMatch": "Совпадений не найдено.", + "cancel": "Отмена", + "saving": "Сохранение…", + "chips": { + "total": "арендаторов", + "active": "активных", + "readable": "с доступом" + }, + "status": { + "ACTIVE": "Активен", + "SUSPENDED": "Приостановлен", + "TERMINATED": "Закрыт" + }, + "support": { + "NONE": "Нет доступа", + "READ": "Доступ на чтение", + "FULL": "Полный доступ", + "hint": "Выдаётся арендатором, а не вами. Изменить это может только его администратор." + }, + "card": { + "edit": "Изменить", + "activate": "Активировать", + "deactivate": "Деактивировать", + "deletePermanent": "Удалить безвозвратно", + "noAccess": "Этот арендатор не предоставил вам доступ.", + "loadingStats": "Чтение…", + "enter": "Войти" + }, + "stats": { + "users": "Пользователи", + "datasources": "Источники", + "openAlerts": "Открытые оповещения", + "ai": "ИИ сегодня", + "noLimit": "без лимита" + }, + "fields": { + "name": "Название", + "domain": "Домен", + "domainHint": "По какому адресу доступен арендатор. Любой запрос на этот хост попадает в его данные.", + "adminEmail": "Почта администратора", + "adminEmailHint": "Он получит приглашение, чтобы задать собственный пароль.", + "status": "Статус", + "suspendedWarning": "Приостановленный арендатор не сможет войти. Его данные сохраняются.", + "aiLimit": "Лимит запросов к ИИ", + "aiLimitHint": "Операционный лимит в сутки. Без лимита расход идёт по лицензии экземпляра.", + "aiLimitToggle": "Ограничить этого арендатора" + }, + "create": { + "title": "Новый арендатор", + "subtitle": "Создаёт арендатора и приглашает его первого администратора.", + "submit": "Создать арендатора" + }, + "edit": { + "title": "Изменение арендатора", + "subtitle": "Доступа поддержки здесь нет: его выдаёт только сам арендатор.", + "submit": "Сохранить" + }, + "terminate": { + "title": "Деактивировать этого арендатора?", + "body": "Никто из {{name}} не сможет войти. Данные сохраняются, так что это обратимо, но клиент отключается сейчас.", + "confirmLabel": "Введите {{name}} для подтверждения", + "submit": "Деактивировать" + }, + "reactivate": { + "title": "Активировать этого арендатора?", + "body": "{{name}} снова сможет войти. Сохранённые данные восстанавливаются как есть.", + "submit": "Активировать" + }, + "deletePermanent": { + "title": "Удалить этого арендатора навсегда?", + "body": "Все следы {{name}} — пользователи, источники данных, дашборды, оповещения, интеграции — будут стёрты. Это нельзя отменить.", + "confirmLabel": "Введите {{name}} для подтверждения", + "submit": "Удалить навсегда" + }, + "toast": { + "created": "Арендатор создан", + "updated": "Арендатор обновлён", + "terminated": "Арендатор закрыт", + "reactivated": "Арендатор восстановлен", + "permanentlyDeleted": "Арендатор удалён безвозвратно", + "domainInUse": "Этот домен уже занят", + "noPermission": "У вас нет прав на это действие", + "notFound": "Арендатор не найден", + "invalidRequest": "Некорректный запрос", + "operationFailed": "Операция не выполнена" + }, + "switcher": { + "aria": "Switch tenant", + "self": "Default tenant", + "create": "Create tenant" + } }, - "agent": { - "placeholder": "Расследовать индикатор…", - "ask": "Спросить агента-аналитика", - "intro": "Спрашивайте о любом индикаторе. Агент напрямую обращается к ThreatWinds и показывает свою работу.", - "send": "Отправить", - "stop": "Остановить", - "thinking": "размышление…", - "suggestionInvestigate": "Расследуйте 8.8.8.8 и скажите, является ли он вредоносным", - "suggestionInfrastructure": "Какая инфраструктура связана с google.com?", - "suggestionCounts": "Покажите, сколько сущностей существует по каждому типу" + "supportAccess": { + "title": "Доступ поддержки", + "intro": "Тот, кто обслуживает этот экземпляр, не может заглянуть в ваши данные без вашего разрешения. По умолчанию здесь не выдано ничего, и вы можете отозвать доступ в любой момент.", + "loading": "Загрузка…", + "loadFailed": "Не удалось прочитать текущую настройку.", + "retry": "Повторить", + "currentBadge": "сейчас", + "save": "Сохранить", + "saving": "Сохранение…", + "levels": { + "NONE": { + "name": "Нет доступа", + "desc": "Оператор видит только то, что ваш арендатор существует. Любые запросы к вашим данным отклоняются." + }, + "READ": { + "name": "Только чтение", + "desc": "Оператор может смотреть ваши оповещения, журналы и настройки, чтобы помочь. Изменить он ничего не может: любая запись отклоняется, какая бы роль у него ни была." + }, + "FULL": { + "name": "Полный доступ", + "desc": "Оператор может действовать в вашем арендаторе как администратор: менять настройки, пользователей и сценарии реагирования." + } + }, + "fullWarning": "Полный доступ позволяет менять всё от вашего имени. Выдавайте его на время работ и возвращайте обратно после.", + "revokeNote": "Все действия оператора здесь попадают в ваш журнал аудита.", + "toast": { + "granted": "Доступ поддержки обновлён", + "revoked": "Доступ поддержки отозван", + "forbidden": "Менять это может только администратор этого арендатора", + "invalid": "Некорректный запрос", + "failed": "Не удалось сохранить изменение" + } }, - "canvas": { - "title": "Результаты", - "empty": "Результаты этого диалога появляются здесь.", - "tile": "Выровнять", - "closeAll": "Закрыть все", - "pinOut": "Открыть {{title}} как панель", - "loading": "загрузка…", - "failed": "не удалось загрузить", - "noRelations": "связанных сущностей нет", - "noGeo": "геолокация не зафиксирована", - "noResults": "совпадений нет", - "matches": "совпадений: {{total}}", - "panelName": "{{title}} — {{kind}}", - "movePanel": "Переместить {{title}}", - "resizePanel": "Изменить размер {{title}}", - "closePanel": "Закрыть {{title}}", - "collapse": "Свернуть {{title}}", - "expand": "Развернуть {{title}}", - "kind": { - "entity": "досье", - "graph": "связи", - "geo": "геолокация", - "search": "поиск" - } + "supportSession": { + "inside": "Вы работаете внутри {{name}}", + "readOnly": "только чтение — запись отклоняется", + "full": "полный доступ — изменения здесь настоящие", + "leave": "Выйти" + }, + "platformBroadcast": { + "button": "Применить ко всем арендаторам", + "action": { + "create": "Массовое создание: {{resource}}", + "update": "Массовое обновление: {{resource}}", + "delete": "Массовое удаление: {{resource}}", + "toggle": "Массовое переключение: {{resource}}", + "enable": "Массовое включение: {{resource}}", + "activate": "Массовая активация: {{resource}}", + "test": "Массовый тест: {{resource}}", + "upload": "Массовая загрузка ресурса {{resource}}" + }, + "resource": { + "pipeline": "конвейер", + "correlationRule": "правило корреляции", + "soarFlow": "SOAR-поток", + "framework": "фреймворк", + "control": "контроль", + "smtp": "SMTP", + "idp": "провайдер идентификации", + "branding": "брендинг" + }, + "warning": { + "title": "Это действие будет выполнено для каждого выбранного арендатора.", + "body": "Ошибки по арендаторам сообщаются после выполнения и не откатываются." + }, + "allTenants": "Применить ко всем арендаторам", + "excludesDefault": "Арендатор платформы исключён из этого действия.", + "searchPlaceholder": "Поиск арендаторов…", + "loading": "Загрузка арендаторов…", + "empty": "Арендаторы не найдены.", + "targetCount": "Будет применено к {{count}} арендатор(ам).", + "platformTenant": "платформа", + "confirm": "Применить к {{count}} арендатор(ам)", + "result": { + "succeeded": "Успешно", + "noneSucceeded": "Ни один арендатор не завершился успешно.", + "failed": "Не удалось", + "noneFailed": "Ошибок нет." + } }, - "graph": { - "nodes_one": "{{count}} узел", - "nodes_other": "{{count}} узлов", - "edges_one": "{{count}} ребро", - "edges_other": "{{count}} рёбер", - "clickToPivot": "клик для перехода", - "malicious": "вредоносный", - "unknown": "неизвестный", - "benign": "безопасный" + "tiAnalyst": { + "console": { + "subtitle": "Рабочее пространство аналитика", + "model": "Модель", + "resizeResults": "Изменить размер панели результатов", + "resizeHint": "Перетащите, чтобы изменить размер · двойной клик — сброс" + }, + "conv": { + "title": "Диалоги", + "allConversations": "Все диалоги", + "empty": "Диалогов пока нет.", + "new": "Новый диалог", + "newTitle": "Название диалога", + "selectPrompt": "Выберите диалог или начните новый.", + "running": "выполняется", + "delete": "Удалить {{title}}", + "unread_one": "{{count}} непрочитанное сообщение", + "unread_other": "{{count}} непрочитанных сообщения", + "transcript": "Транскрипция диалога" + }, + "agent": { + "placeholder": "Расследовать индикатор…", + "ask": "Спросить агента-аналитика", + "intro": "Спрашивайте о любом индикаторе. Агент напрямую обращается к ThreatWinds и показывает свою работу.", + "send": "Отправить", + "stop": "Остановить", + "thinking": "размышление…", + "suggestionInvestigate": "Расследуйте 8.8.8.8 и скажите, является ли он вредоносным", + "suggestionInfrastructure": "Какая инфраструктура связана с google.com?", + "suggestionCounts": "Покажите, сколько сущностей существует по каждому типу" + }, + "canvas": { + "title": "Результаты", + "empty": "Результаты этого диалога появляются здесь.", + "tile": "Выровнять", + "closeAll": "Закрыть все", + "pinOut": "Открыть {{title}} как панель", + "loading": "загрузка…", + "failed": "не удалось загрузить", + "noRelations": "связанных сущностей нет", + "noGeo": "геолокация не зафиксирована", + "noResults": "совпадений нет", + "matches": "совпадений: {{total}}", + "panelName": "{{title}} — {{kind}}", + "movePanel": "Переместить {{title}}", + "resizePanel": "Изменить размер {{title}}", + "closePanel": "Закрыть {{title}}", + "collapse": "Свернуть {{title}}", + "expand": "Развернуть {{title}}", + "kind": { + "entity": "досье", + "graph": "связи", + "geo": "геолокация", + "search": "поиск" + } + }, + "graph": { + "nodes_one": "{{count}} узел", + "nodes_other": "{{count}} узлов", + "edges_one": "{{count}} ребро", + "edges_other": "{{count}} рёбер", + "clickToPivot": "клик для перехода", + "malicious": "вредоносный", + "unknown": "неизвестный", + "benign": "безопасный" + }, + "entity": { + "reputation": "Репутация", + "accuracy": "Точность", + "worst": "Худшая", + "best": "Лучшая", + "relations": "Граф связей", + "history": "История", + "geolocations": "Геолокации", + "associations": "Ассоциации", + "radius": "r={{radius}}м", + "askAgentBtn": "Спросить агента", + "askAgent": "Оцените {{type}} {{value}} (сущность id {{id}}). Это угроза?" + }, + "tool": { + "querying": "запрос…", + "notRetained": "Результат не сохранён.", + "expand": "Показать запрос и результат", + "collapse": "Скрыть запрос и результат", + "noIntel": "По «{{value}}» нет записанных данных об угрозах.", + "noMatches": "Совпадений нет.", + "matches": "совпадений по «{{query}}»: {{items}}", + "more": "ещё +{{count}}", + "reported": "Сообщено в общий корпус ThreatWinds. Ингест асинхронный, пока не ищется.", + "skippedAssociations": "Не записано (тип не определён): {{values}}" + } }, - "entity": { - "reputation": "Репутация", - "accuracy": "Точность", - "worst": "Худшая", - "best": "Лучшая", - "relations": "Граф связей", - "history": "История", - "geolocations": "Геолокации", - "associations": "Ассоциации", - "radius": "r={{radius}}м", - "askAgentBtn": "Спросить агента", - "askAgent": "Оцените {{type}} {{value}} (сущность id {{id}}). Это угроза?" + "threatwinds": { + "title": "Интеграция ThreatWinds", + "subtitle": "Поделитесь инцидентами этой инстанции с общественным фидом ThreatWinds.", + "feeds": "Включить фиды", + "feedsHint": "Если включено, события сверяются с фидами угроз ThreatWinds.", + "contribute": "Передавать инциденты", + "contributeHint": "Если включено, инциденты этой инстанции отправляются в ThreatWinds.", + "loading": "Загрузка состояния интеграции…", + "failed": "Не удалось загрузить состояние интеграции ThreatWinds.", + "retry": "Повторить", + "toast": { + "enabled": "Передача включена", + "disabled": "Передача выключена", + "failed": "Не удалось обновить настройку передачи" + } }, - "tool": { - "querying": "запрос…", - "notRetained": "Результат не сохранён.", - "expand": "Показать запрос и результат", - "collapse": "Скрыть запрос и результат", - "noIntel": "По «{{value}}» нет записанных данных об угрозах.", - "noMatches": "Совпадений нет.", - "matches": "совпадений по «{{query}}»: {{items}}", - "more": "ещё +{{count}}", - "reported": "Сообщено в общий корпус ThreatWinds. Ингест асинхронный, пока не ищется.", - "skippedAssociations": "Не записано (тип не определён): {{values}}" - } - }, - "threatwinds": { - "title": "Интеграция ThreatWinds", - "subtitle": "Поделитесь инцидентами этой инстанции с общественным фидом ThreatWinds.", - "feeds": "Включить фиды", - "feedsHint": "Если включено, события сверяются с фидами угроз ThreatWinds.", - "contribute": "Передавать инциденты", - "contributeHint": "Если включено, инциденты этой инстанции отправляются в ThreatWinds.", - "loading": "Загрузка состояния интеграции…", - "failed": "Не удалось загрузить состояние интеграции ThreatWinds.", - "retry": "Повторить", - "toast": { - "enabled": "Передача включена", - "disabled": "Передача выключена", - "failed": "Не удалось обновить настройку передачи" - } - }, - "liveOps": { - "header": "Мониторинг онлайн", - "live": "В ЭФИРЕ", - "replay": "ВОСПРОИЗВЕДЕНИЕ", - "statLastHour": "Последний час", - "statHigh": "Высокие", - "statOpen": "Открытые", - "statAttackers": "Атакующие", - "listTitle": "Оповещения", - "listShown": "показано: {{count}}", - "listShow": "Показать список оповещений", - "listHide": "Скрыть список", - "agoJust": "только что", - "agoMin": "{{count}} мин назад", - "agoH": "{{count}} ч назад", - "more": "Ещё", - "less": "Меньше", - "loading": "Загрузка оповещений…", - "error": "Не удалось загрузить оповещения: {{msg}}", - "empty": "В хранилище нет оповещений.", - "onStage": "На сцене", - "hideDetails": "Скрыть эту панель", - "showDetails": "Показать детали", - "inIncident": "В инциденте", - "openInAlerts": "Открыть в оповещениях", - "involved": "Затронуты", - "askSocAi": "Спросить SOC-AI", - "askExplain": "Объясни эту атаку и скажи, что делать дальше", - "askFp": "Это ложное срабатывание?", - "askAttacker": "Что ещё сделал этот атакующий?", - "timCount": "{{count}} оповещений за последние {{range}}", - "timPrev": "Предыдущее оповещение", - "timNext": "Следующее оповещение", - "timReplay": "Проиграть окно", - "timStop": "Остановить воспроизведение", - "timLive": "В ЭФИРЕ", - "timNow": "сейчас", - "kb": { - "bruteForce": "Брутфорс", - "outbound": "Соединение с вредоносным адресом", - "lateral": "Горизонтальное перемещение", - "malware": "Зловредное выполнение на хосте", - "webAttack": "Веб-атака", - "travel": "Невозможное путешествие", - "scan": "Скан портов", - "cloud": "Рискованное изменение в облаке", - "generic": "Обнаружение", - "ransomware": "Вымогательское ПО на хосте", - "persistence": "Механизм персистентности", - "exfil": "Экфильтрация данных", - "defenseEvasion": "Обход защитных мер", - "privEsc": "Эскалация привилегий", - "userExec": "Пользователь открыл вредоносный файл", - "softwareDeploy": "Программное обеспечение развёрнуто на хост", - "phishing": "Открыта фишинговая почта", - "processInjection": "Код внедрён в процесс", - "credDump": "Утечка учётных данных", - "dataDestruction": "Данные уничтожены", - "toolDownload": "Инструмент загружен и запущен", - "c2tunnel": "C2 через туннель", - "iocMatch": "IOC угрозы обнаружен", - "perimeterDetect": "Обнаружение периметра/IDS", - "accountChange": "Изменение учётки или политики", - "kerberosTicket": "Злоупотребление билетами Kerberos", - "powershellAbuse": "Злоупотребление скриптами", - "reverseShell": "Обратный shell", - "vmEscape": "Взлом VM/гипервизора" + "liveOps": { + "header": "Мониторинг онлайн", + "live": "В ЭФИРЕ", + "replay": "ВОСПРОИЗВЕДЕНИЕ", + "statLastHour": "Последний час", + "statHigh": "Высокие", + "statOpen": "Открытые", + "statAttackers": "Атакующие", + "listTitle": "Оповещения", + "listShown": "показано: {{count}}", + "listShow": "Показать список оповещений", + "listHide": "Скрыть список", + "agoJust": "только что", + "agoMin": "{{count}} мин назад", + "agoH": "{{count}} ч назад", + "more": "Ещё", + "less": "Меньше", + "loading": "Загрузка оповещений…", + "error": "Не удалось загрузить оповещения: {{msg}}", + "empty": "В хранилище нет оповещений.", + "onStage": "На сцене", + "hideDetails": "Скрыть эту панель", + "showDetails": "Показать детали", + "inIncident": "В инциденте", + "openInAlerts": "Открыть в оповещениях", + "involved": "Затронуты", + "askSocAi": "Спросить SOC-AI", + "askExplain": "Объясни эту атаку и скажи, что делать дальше", + "askFp": "Это ложное срабатывание?", + "askAttacker": "Что ещё сделал этот атакующий?", + "timCount": "{{count}} оповещений за последние {{range}}", + "timPrev": "Предыдущее оповещение", + "timNext": "Следующее оповещение", + "timReplay": "Проиграть окно", + "timStop": "Остановить воспроизведение", + "timLive": "В ЭФИРЕ", + "timNow": "сейчас", + "kb": { + "bruteForce": "Брутфорс", + "outbound": "Соединение с вредоносным адресом", + "lateral": "Горизонтальное перемещение", + "malware": "Зловредное выполнение на хосте", + "webAttack": "Веб-атака", + "travel": "Невозможное путешествие", + "scan": "Скан портов", + "cloud": "Рискованное изменение в облаке", + "generic": "Обнаружение", + "ransomware": "Вымогательское ПО на хосте", + "persistence": "Механизм персистентности", + "exfil": "Экфильтрация данных", + "defenseEvasion": "Обход защитных мер", + "privEsc": "Эскалация привилегий", + "userExec": "Пользователь открыл вредоносный файл", + "softwareDeploy": "Программное обеспечение развёрнуто на хост", + "phishing": "Открыта фишинговая почта", + "processInjection": "Код внедрён в процесс", + "credDump": "Утечка учётных данных", + "dataDestruction": "Данные уничтожены", + "toolDownload": "Инструмент загружен и запущен", + "c2tunnel": "C2 через туннель", + "iocMatch": "IOC угрозы обнаружен", + "perimeterDetect": "Обнаружение периметра/IDS", + "accountChange": "Изменение учётки или политики", + "kerberosTicket": "Злоупотребление билетами Kerberos", + "powershellAbuse": "Злоупотребление скриптами", + "reverseShell": "Обратный shell", + "vmEscape": "Взлом VM/гипервизора" + }, + "replayTip": "Проиграть все события этого окна по порядку", + "liveTip": "Следовать за новыми событиями по мере их поступления", + "playAgain": "Проиграть это событие снова", + "alertAt": "{{name}} в {{time}}", + "netInternet": "Интернет", + "netInternal": "Внутренняя сеть", + "scUser": "пользователь: {{account}}", + "scWrongPassword": "✕ неверный пароль", + "scSignedIn": "✓ вошёл", + "scSignedInAs": "вошёл как {{account}}", + "scFailedSignins": "Неудачные входы", + "scBlocked": "🛡 {{name}} заблокирован", + "scSessionAs": "сеанс как {{account}}", + "scHost": "Хост · {{name}}", + "scFiles": "Документы", + "scBackups": "Теневые копии", + "scRansomNote": "🔒 ЗАПИСКА О ВЫКУПЕ", + "scShadows": "✕ теневые копии удалены", + "scPersist": "Персистентность", + "scReboot": "переживает перезагрузки — установлена бэкдор", + "scCloud": "Внешнее хранилище", + "scChunk": "данные", + "scExfilBytes": "Экфильтровано данных", + "scProcessTree": "Дерево процессов", + "scDns": "DNS? {{host}}", + "scThreatIntel": "Threat intel: Тревожно (-3)", + "scConnDropped": "✕ соединение разорвано", + "scPortsProbed": "Проверенные порты", + "scSignIn": "✓ вход", + "scKmInMin": "{{km}} км за {{min}} мин", + "scAbroad": "за границей", + "scDropped": "{{status}} заблокирован", + "scBeacon": "маяк", + "capBrute0": "{{name}}{{sub}} начинает подбирать пароли против {{where}}.", + "capBruteVpn": "VPN на {{name}}", + "capBrute1": "{{attempts}} неудачных входов за {{minutes}} минут с перебором {{count}} учётных записей.", + "capBrute2": "Вход как {{account}} проходит сразу после неудач: пароль угадан.", + "capBrute3": "Корреляция неудач между источниками: один атакующий, много записей.", + "capBrute4": "Заблокируйте {{name}} на границе{{reset}}.", + "capBruteReset": " и сбросьте {{account}}", + "capOut1": "{{who}} запрашивает {{dest}}.", + "capOut2": "Соединяется наружу по порту {{port}}{{through}}.", + "capOutThrough": " через {{name}}", + "capOut3": "Threat intelligence совпало с {{dest}}: {{kind}}.", + "capOut4": "Соединение было разорвано, и сработало событие для проверки машины.", + "capOut5": "Соединение повторяется: {{name}} вероятно заражён. Изолируйте его и найдите процесс.", + "capLat0": "{{name}}{{user}} обращается к {{to}} внутри сети.", + "capLatUser": " ({{user}})", + "capLat1": "Аутентифицируется как {{account}} с помощью {{how}}.", + "capLatHowHash": "украденного хеша пароля", + "capLatHowKerb": "сервисных тикетов Kerberos, которые можно взломать офлайн", + "capLatHowAsrep": "ответа Kerberos для записи без предварительной аутентификации", + "capLatHowSmb": "устаревшего протокола SMBv1", + "capLatHowRdp": "удалённых сессий и общих папок", + "capLat2": "{{to}} принимает сессию: атакующий теперь перемещается между машинами.", + "capLat3": "Отключите {{account}} и проверьте обе машины.", + "capMal0": "На {{host}}{{user}} выполняется {{proc}}.", + "capMalUser": ", {{user}}", + "capMal1": "{{p0}} запускает {{p1}}: необычно для этой программы.", + "capMalChild": "дочерний процесс", + "capMal2": "Выполняется {{name}}: {{detail}}.", + "capMalKnown": "известная техника атаки", + "capMal3": "Остановите процесс или изолируйте {{host}}.", + "capWeb0": "{{name}} зондирует сервер {{to}}.", + "capWeb1": "Отправляет атакующие нагрузки: {{payloads}}…", + "capWeb2": "{{perimeter}} распознаёт сигнатуры атаки и отбрасывает запросы.", + "capWeb2b": "IPS распознаёт сигнатуры атаки и отбрасывает запросы.", + "capWeb3": "Часть запросов достигает {{to}}; сервер отвечает ошибками и одним 200 OK.", + "capWeb4": "Заблокируйте {{name}} и проверьте журналы сервера.", + "capTrv0": "{{user}} входит из {{city}}, как обычно.", + "capTrv1": "Через {{gap}} минут та же запись входит из {{city}}, {{country}}.", + "capTrvFar": "далеко", + "capTrv2": "{{km}} км за {{gap}} минут: никто так не перемещается. Пароль, вероятно, украден.", + "capTrv3": "Отозвите сессии и сбросьте пароль {{user}}.", + "capScn0": "{{name}} начинает стучаться в {{to}}, порт за портом.", + "capScn1": "{{count}} портов зондировано за секунды: SSH, SMB, RDP, базы данных, веб-консоли…", + "capScn2": "Порты {{open}} отвечают; всё остальное закрыто или отфильтровано.", + "capScn3": "Обычно первый шаг атаки: заблокируйте источник.", + "capCl0": "{{name}} входит в {{cloud}}{{from}}.", + "capClFrom": " из {{country}}", + "capClFromDef": "вне компании", + "capCl1": "Они меняют {{what}}.", + "capCl3": "Подтвердите, что это было запланировано, или отмените.", + "capGen0": "{{src}} → {{tgt}}", + "capGen1": "{{what}}", + "capGenNew": "Новое обнаружение", + "capGen2": "Событие: {{name}}.", + "capAlertRaised": "Событие: {{name}}. ", + "capBlocked": "{{ip}} теперь заблокирован на {{on}}: трафик останавливается здесь.", + "destUnknown": "неизвестный адресат", + "titleBrute": "Подбор паролей с {{name}} против {{to}}", + "titleOut": "{{name}} связывается с {{to}}", + "titleLat": "{{name}} перемещается на {{to}} как {{account}}", + "titleMal": "{{name}} на {{to}}", + "titleWeb": "Веб-атака с {{name}} против {{to}}", + "titleTrv": "{{name}} входит с двух континентов", + "titleScn": "Сканирование портов с {{name}}", + "titleCl": "{{what}} изменено в {{to}}", + "titleAlert": "Событие", + "dLsass": "сливает память LSASS, чтобы украсть пароли", + "dMiner": "майнит криптовалюту на CPU сервера", + "dRev": "открывает интерактивную shell обратно атакующему", + "dKey": "экспортирует сохранённые пароли из keychain", + "dTask": "создаёт задачу, запускающую полезную нагрузку при каждом входе", + "dAudit": "стирает журнал безопасности Windows", + "dFw": "удаляет правила файрвола хоста", + "dShadow": "удаляет теневые копии томов перед шифрованием", + "dDump": "инструмент для извлечения учётных данных", + "dDl": "скачивает инструмент в записываемую папку", + "dPs": "выполняет закодированную команду", + "capRan0": "На {{host}}{{user}} процесс начинает одновременно трогать сотни файлов.", + "capRanUser": ", {{user}}", + "capRan1": "Файлы переименовываются с расширением {{exts}}: данные шифруются на месте.", + "capRan2": "Заводится записка о выкупе: атакующий требует оплату за восстановление данных.", + "capRan2b": "Резервные копии и теневые копии удаляются: лёгкого возврата нет.", + "capRan3": "Восстановить из офлайн-резервов и найти точку входа, пока шифрование не разрослось.", + "titleRan": "Вымогательское ПО шифрует {{to}}", + "capPer0": "На {{host}}{{user}} что-то записывает в места автозапуска системы.", + "capPer1": "Он размещает {{what}}: это запускается автоматически при каждом старте или входе.", + "capPer2": "Последний элемент на месте: {{what}}. Присутствие теперь переживает перезагрузки.", + "capPer3": "Удалить артефакты персистентности и искать первичный вектор заражения.", + "titlePer": "Персистентность установлена на {{to}} через {{what}}", + "dPersistCron": "запускает полезную нагрузку по расписанию", + "dPersistSd": "запускает полезную нагрузку при старте", + "dPersistLaunch": "запускает полезную нагрузку при входе пользователя", + "dPersistKey": "даёт атакующему повторный доступ по SSH", + "dPersistRc": "запускает полезную нагрузку в каждой новой оболочке", + "dPersistPs": "запускает полезную нагрузку в каждой сессии PowerShell", + "dPersistPay": "сам бинарник полезной нагрузки", + "capExf0": "На {{host}}{{user}} конфиденциальные данные сводятся в один архив.", + "capExf1": "Начинается их передача наружу через {{tool}}.", + "capExf2": "Данные прибывают в {{dest}}: они уже за пределами компании.", + "capExf3": "Блокировать передачу, отозвать доступ к {{dest}} и выяснить, кто может к ним добраться.", + "titleExf": "{{name}} выводит данные на {{to}}", + "scDefenses": "Защитные меры", + "scDisabled": "✕ отключено", + "scLogsCleared": "🗑 журналы очищены", + "dEvLog": "аудит-след", + "dEvEnf": "принудительное исполнение", + "capEv0": "На {{host}} атакующий начинает трогать то, что за ним следит.", + "capEv1": "{{what}} отключено: ещё одно наблюдение исчезло.", + "capEv2": "Журналы очищены: след его действий исчезает.", + "capEv2b": "С отключённым {{what}} хост слеп для атакующего.", + "capEv3": "Вернуть отключённые средства и сохранить оставшиеся журналы, пока они не исчезли.", + "titleEv": "Защитные меры отключены на {{to}}", + "scNormalUser": "обычный пользователь", + "scToken": "токен", + "dEvUac": "обход UAC", + "dEvToken": "похищен токен", + "dEvSuid": "злоупотребление setuid-бинарником", + "dEvSudo": "злоупотребление кэшем sudo", + "dEvExploit": "эксплуатация ядра", + "dEvDefault": "преодолен порог привилегий", + "capPe0": "На {{host}} сессия работает обычным пользователем.{{user}}", + "capPeUser": ", {{user}}", + "capPe1": "Он использует {{method}}, чтобы достичь более высокого уровня привилегий.", + "capPe2": "Команды теперь выполняются как {{account}}: полный контроль хоста.", + "capPe3": "Завершить эскалированную сессию и проверить, что мог задеть {{account}}.", + "titlePe": "Эскалация привилегий на {{to}} через {{method}}", + "alertRaised": "Событие создано", + "userExec": "Пользователь открыл вредоносный файл", + "softwareDeploy": "Программное обеспечение развёрнуто на хост", + "phishing": "Открыта фишинговая почта", + "processInjection": "Код внедрён в процесс", + "credDump": "Утечка учётных данных", + "dataDestruction": "Данные уничтожены", + "toolDownload": "Инструмент загружен и запущен", + "c2tunnel": "C2 через туннель", + "scExec": "Выполнение", + "scPayload": "→ вредоносный полезный груз", + "capUe0": "На {{host}}{{user}} пользователь скачивает файл и открывает его.", + "capUeUser": ", {{user}}", + "capUe1": "Файл открыт: {{file}} доверяется и выполняется.", + "capUe2": "{{app}} запускает дочерний процесс, который выполняет {{payload}}.", + "capUe3": "Поместить файл в карантин, заблокировать его хеш и проверить другие хосты, открывшие его.", + "titleUe": "{{file}} открыт на {{to}}", + "scDeploy": "Развёртывание", + "capSd0": "{{src}} разворачивает программное обеспечение на {{to}} по сети.", + "capSd1": "Используется {{tool}}: канал, который устанавливает без участия пользователя.", + "capSd2": "Пакет установлен на {{to}} и запускается вместе с ним.", + "capSd3": "Остановить развёртывание, удалить установленный компонент и проверить, что он делал.", + "titleSd": "Программное обеспечение развёрнуто с {{src}} на {{to}}", + "scAttachment": "вложение открыто", + "capPh0": "{{name}} отправляет фишинговое письмо в компанию.", + "capPh1": "Письмо попадает в почтовый ящик {{user}} и открывается.", + "capPh2": "Вложение выполняется: {{file}} запускается на машине.", + "capPh3": "Поместить письмо в карантин, заблокировать отправителя и удалить {{file}} с машины {{user}}.", + "titlePh": "Фишинговое письмо открыл {{user}} (от {{from}})", + "scInject": "Внедрение", + "scInside": "— код внутри доверенного процесса", + "capPi0": "На {{host}} запускается лоадер атакующего: {{injector}}.", + "capPi1": "Он внедряет код в доверенный процесс: {{victim}}.", + "capPi2": "{{victim}} теперь выполняет код атакующего со своими привилегиями.", + "capPi3": "Завершить внедрённый код, удалить лоадер и искать других жертв.", + "titlePi": "{{injector}} внедряет код в {{victim}}", + "scCred": "Хранилище учётных данных", + "scSecrets": "{{n}} секретов", + "scSecret": "секрет", + "scStolen": "✕ учётные данные похищены", + "capCd0": "На {{host}} инструмент начинает читать хранилище учётных данных.", + "capCd1": "Он открывает {{store}} и извлекает содержимое.", + "capCd2": "Пойманы {{n}} учётных данных: аккаунты, ключи и хеши.", + "capCd3": "Сменить все учётные данные хранилища и искать инструмент сброса.", + "titleCd": "{{store}} сброшен на {{host}}", + "scData": "Данные", + "scDataItem": "набор-{{i}}", + "scGone": "потеряно", + "scNoRecovery": "данные уничтожены", + "capDd0": "На {{host}} что-то начинает стирать данные, а не шифровать.", + "capDd1": "{{n}} наборов данных уничтожаются один за другим.", + "capDd2": "Данные удаляются в сыром виде: без записки, без выкупа, без возврата.", + "capDd3": "Остановить исходный процесс и восстановить остаток из офлайн-резервов.", + "titleDd": "Данные уничтожены на {{host}}", + "scDownload": "байты", + "scExecuted": "запущено", + "capTd0": "{{src}} поставляет инструмент на {{to}}.", + "capTd1": "Он скачивается в запись-доступную папку: {{folder}}.", + "capTd2": "Файл запускается: {{tool}} теперь работает.", + "capTd3": "Удалить инструмент, заблокировать его хеш и проверить, какие хосты его запустили.", + "titleTd": "{{src}} размещает инструмент на {{to}}", + "scTunnel": "скрыто в трафике {{proto}}", + "scTunneled": "Протуннелировано байт", + "capCt0": "{{src}} общается с {{to}} по виду обычному протоколу.", + "capCt1": "Полезная нагрузка спрятана в трафике {{proto}}.", + "capCt2": "Команды и данные проходят границу невидимо, на {{proto}}.", + "capCt3": "Оборвать туннель, заблокировать конечность и проверить, что прошло через него.", + "titleCt": "{{src}} протуннелил C2 через {{proto}} к {{to}}", + "netPerimeter": "Периметр", + "scDc": "Контроллер домена", + "scObject": "Изменённый объект", + "scChangedBy": "изменено", + "scHighRisk": "высокорисковое изменение", + "scTktAsk": "запрос билета", + "scTktUses": "перепроверено на {{n}} сервисов", + "scTerminal": "Терминал", + "scRunning": "…выполняется", + "scAmsiOff": "⚠ AMSI отключён", + "scConn": "TCP {{port}}", + "scShellOn": "$ обратный shell", + "scHypervisor": "Гипервизор", + "scGuestVm": "гостевая VM", + "scConfined": "заперта в госте", + "scEscaped": "вышла на хост", + "scBoundary": "граница гостя нарушена", + "scFeedAsk": "фид? {{ioc}}", + "scFeedBad": "ХУДО", + "scFeedHit": "Разведка: {{kind}}", + "scDroppedAtFw": "✕ отброшено на {{fw}}", + "scTrafficStops": "трафик здесь останавливается", + "scSigHits": "Попадания по сигнатуре", + "capIoc0": "{{src}} соединяется с {{ioc}}.", + "capIoc1": "Разведка о угрозах помечает: {{kind}}.", + "capIoc2": "{{ioc}} в стоп-листе: соединение оборвано.", + "capIoc3": "Заблокировать {{ioc}} на периметре и проверить, что уже ушло из сети.", + "titleIoc": "{{src}} достигает известного {{ioc}}", + "capPd0": "{{name}} шлёт {{sig}} на периметр.", + "capPd1": "{{fw}} совпал с сигнатурой и сработал.", + "capPd2": "Трафик отброшен: периметр выдержал.", + "capPd3": "Трафик проходит через {{fw}}: сигнал информативный.", + "capPd4": "Проверить сигнатуру и заблокировать источник, если он не прекратил.", + "titlePd": "{{sig}} заблокировано на {{fw}}", + "capAc0": "{{who}} изменяет {{what}} на {{host}}.", + "capAc1": "{{what}} модифицирован.", + "capAc2": "{{before}} → {{after}}.", + "capAc3": "Подтвердить, что это было спланировано, или откатить изменение {{who}}.", + "titleAc": "{{what}} изменено на {{host}}", + "capKb0": "{{src}} запрашивает билеты Kerberos у {{dc}}.", + "capKb1": "Полученный {{ticket}} — это {{kind}}.", + "capKb2": "Он повторно использован на {{services}}: DC принимает каждый раз.", + "capKb3": "Сбросить пароль krbtgt и просмотреть выданные билеты за 48 ч.", + "titleKb": "{{src}} подделывает Kerberos-билеты через {{dc}}", + "capPs0": "На {{host}} запускается скрипт с закодированным содержимым.", + "capPs1": "Он декодирует команду и отключает сенсор антивируса (AMSI).", + "capPs2": "Декодированная команда выполняется: это полезная нагрузка, не скрипт.", + "capPs2a": "Сначала отключают AMSI, затем декодированная команда выполняется незаметно.", + "capPs3": "Заблокировать хеш, поискать другие машины с тем же скриптом.", + "titlePs2": "Закодированный скрипт выполняется на {{host}}", + "capRs0": "На {{host}} процесс открывает сокет наружу.", + "capRs1": "Он переподключается к {{name}} на порт {{port}}: обратный shell.", + "capRs2": "Появляется приглашение: атакующий теперь может печатать команды на хосте.", + "capRs3": "Оборвать соединение, изолировать {{host}} и посмотреть, что было введено.", + "titleRs": "Обратный shell открыт на {{host}}", + "capVm0": "Гостевая VM {{guest}} запускает процесс с хост-доступом.", + "capVm1": "Он пытается пересечь границу гипервизора.", + "capVm2": "Процесс выполняется на хосте {{host}}: гость больше не клетка.", + "capVm3": "Паниковать гипервизор, сделать снапшот гостя и пересобрать.", + "titleVm": "Гость {{guest}} вырвался на {{host}}", + "listNew": "Новый", + "newAlertsCount_one": "{{count}} новый алерт", + "newAlertsCount_few": "{{count}} новых алерта", + "newAlertsCount_many": "{{count}} алертов", + "newAlertsCount_other": "{{count}} новых алертов", + "statTotal": "Всего", + "timPage": "Страница {{p}}/{{n}}", + "timPagePrev": "Предыдущая страница", + "timPageNext": "Следующая страница", + "newAlerts": "Новые алерты" }, - "replayTip": "Проиграть все события этого окна по порядку", - "liveTip": "Следовать за новыми событиями по мере их поступления", - "playAgain": "Проиграть это событие снова", - "alertAt": "{{name}} в {{time}}", - "netInternet": "Интернет", - "netInternal": "Внутренняя сеть", - "scUser": "пользователь: {{account}}", - "scWrongPassword": "✕ неверный пароль", - "scSignedIn": "✓ вошёл", - "scSignedInAs": "вошёл как {{account}}", - "scFailedSignins": "Неудачные входы", - "scBlocked": "🛡 {{name}} заблокирован", - "scSessionAs": "сеанс как {{account}}", - "scHost": "Хост · {{name}}", - "scFiles": "Документы", - "scBackups": "Теневые копии", - "scRansomNote": "🔒 ЗАПИСКА О ВЫКУПЕ", - "scShadows": "✕ теневые копии удалены", - "scPersist": "Персистентность", - "scReboot": "переживает перезагрузки — установлена бэкдор", - "scCloud": "Внешнее хранилище", - "scChunk": "данные", - "scExfilBytes": "Экфильтровано данных", - "scProcessTree": "Дерево процессов", - "scDns": "DNS? {{host}}", - "scThreatIntel": "Threat intel: Тревожно (-3)", - "scConnDropped": "✕ соединение разорвано", - "scPortsProbed": "Проверенные порты", - "scSignIn": "✓ вход", - "scKmInMin": "{{km}} км за {{min}} мин", - "scAbroad": "за границей", - "scDropped": "{{status}} заблокирован", - "scBeacon": "маяк", - "capBrute0": "{{name}}{{sub}} начинает подбирать пароли против {{where}}.", - "capBruteVpn": "VPN на {{name}}", - "capBrute1": "{{attempts}} неудачных входов за {{minutes}} минут с перебором {{count}} учётных записей.", - "capBrute2": "Вход как {{account}} проходит сразу после неудач: пароль угадан.", - "capBrute3": "Корреляция неудач между источниками: один атакующий, много записей.", - "capBrute4": "Заблокируйте {{name}} на границе{{reset}}.", - "capBruteReset": " и сбросьте {{account}}", - "capOut1": "{{who}} запрашивает {{dest}}.", - "capOut2": "Соединяется наружу по порту {{port}}{{through}}.", - "capOutThrough": " через {{name}}", - "capOut3": "Threat intelligence совпало с {{dest}}: {{kind}}.", - "capOut4": "Соединение было разорвано, и сработало событие для проверки машины.", - "capOut5": "Соединение повторяется: {{name}} вероятно заражён. Изолируйте его и найдите процесс.", - "capLat0": "{{name}}{{user}} обращается к {{to}} внутри сети.", - "capLatUser": " ({{user}})", - "capLat1": "Аутентифицируется как {{account}} с помощью {{how}}.", - "capLatHowHash": "украденного хеша пароля", - "capLatHowKerb": "сервисных тикетов Kerberos, которые можно взломать офлайн", - "capLatHowAsrep": "ответа Kerberos для записи без предварительной аутентификации", - "capLatHowSmb": "устаревшего протокола SMBv1", - "capLatHowRdp": "удалённых сессий и общих папок", - "capLat2": "{{to}} принимает сессию: атакующий теперь перемещается между машинами.", - "capLat3": "Отключите {{account}} и проверьте обе машины.", - "capMal0": "На {{host}}{{user}} выполняется {{proc}}.", - "capMalUser": ", {{user}}", - "capMal1": "{{p0}} запускает {{p1}}: необычно для этой программы.", - "capMalChild": "дочерний процесс", - "capMal2": "Выполняется {{name}}: {{detail}}.", - "capMalKnown": "известная техника атаки", - "capMal3": "Остановите процесс или изолируйте {{host}}.", - "capWeb0": "{{name}} зондирует сервер {{to}}.", - "capWeb1": "Отправляет атакующие нагрузки: {{payloads}}…", - "capWeb2": "{{perimeter}} распознаёт сигнатуры атаки и отбрасывает запросы.", - "capWeb2b": "IPS распознаёт сигнатуры атаки и отбрасывает запросы.", - "capWeb3": "Часть запросов достигает {{to}}; сервер отвечает ошибками и одним 200 OK.", - "capWeb4": "Заблокируйте {{name}} и проверьте журналы сервера.", - "capTrv0": "{{user}} входит из {{city}}, как обычно.", - "capTrv1": "Через {{gap}} минут та же запись входит из {{city}}, {{country}}.", - "capTrvFar": "далеко", - "capTrv2": "{{km}} км за {{gap}} минут: никто так не перемещается. Пароль, вероятно, украден.", - "capTrv3": "Отозвите сессии и сбросьте пароль {{user}}.", - "capScn0": "{{name}} начинает стучаться в {{to}}, порт за портом.", - "capScn1": "{{count}} портов зондировано за секунды: SSH, SMB, RDP, базы данных, веб-консоли…", - "capScn2": "Порты {{open}} отвечают; всё остальное закрыто или отфильтровано.", - "capScn3": "Обычно первый шаг атаки: заблокируйте источник.", - "capCl0": "{{name}} входит в {{cloud}}{{from}}.", - "capClFrom": " из {{country}}", - "capClFromDef": "вне компании", - "capCl1": "Они меняют {{what}}.", - "capCl3": "Подтвердите, что это было запланировано, или отмените.", - "capGen0": "{{src}} → {{tgt}}", - "capGen1": "{{what}}", - "capGenNew": "Новое обнаружение", - "capGen2": "Событие: {{name}}.", - "capAlertRaised": "Событие: {{name}}. ", - "capBlocked": "{{ip}} теперь заблокирован на {{on}}: трафик останавливается здесь.", - "destUnknown": "неизвестный адресат", - "titleBrute": "Подбор паролей с {{name}} против {{to}}", - "titleOut": "{{name}} связывается с {{to}}", - "titleLat": "{{name}} перемещается на {{to}} как {{account}}", - "titleMal": "{{name}} на {{to}}", - "titleWeb": "Веб-атака с {{name}} против {{to}}", - "titleTrv": "{{name}} входит с двух континентов", - "titleScn": "Сканирование портов с {{name}}", - "titleCl": "{{what}} изменено в {{to}}", - "titleAlert": "Событие", - "dLsass": "сливает память LSASS, чтобы украсть пароли", - "dMiner": "майнит криптовалюту на CPU сервера", - "dRev": "открывает интерактивную shell обратно атакующему", - "dKey": "экспортирует сохранённые пароли из keychain", - "dTask": "создаёт задачу, запускающую полезную нагрузку при каждом входе", - "dAudit": "стирает журнал безопасности Windows", - "dFw": "удаляет правила файрвола хоста", - "dShadow": "удаляет теневые копии томов перед шифрованием", - "dDump": "инструмент для извлечения учётных данных", - "dDl": "скачивает инструмент в записываемую папку", - "dPs": "выполняет закодированную команду", - "capRan0": "На {{host}}{{user}} процесс начинает одновременно трогать сотни файлов.", - "capRanUser": ", {{user}}", - "capRan1": "Файлы переименовываются с расширением {{exts}}: данные шифруются на месте.", - "capRan2": "Заводится записка о выкупе: атакующий требует оплату за восстановление данных.", - "capRan2b": "Резервные копии и теневые копии удаляются: лёгкого возврата нет.", - "capRan3": "Восстановить из офлайн-резервов и найти точку входа, пока шифрование не разрослось.", - "titleRan": "Вымогательское ПО шифрует {{to}}", - "capPer0": "На {{host}}{{user}} что-то записывает в места автозапуска системы.", - "capPer1": "Он размещает {{what}}: это запускается автоматически при каждом старте или входе.", - "capPer2": "Последний элемент на месте: {{what}}. Присутствие теперь переживает перезагрузки.", - "capPer3": "Удалить артефакты персистентности и искать первичный вектор заражения.", - "titlePer": "Персистентность установлена на {{to}} через {{what}}", - "dPersistCron": "запускает полезную нагрузку по расписанию", - "dPersistSd": "запускает полезную нагрузку при старте", - "dPersistLaunch": "запускает полезную нагрузку при входе пользователя", - "dPersistKey": "даёт атакующему повторный доступ по SSH", - "dPersistRc": "запускает полезную нагрузку в каждой новой оболочке", - "dPersistPs": "запускает полезную нагрузку в каждой сессии PowerShell", - "dPersistPay": "сам бинарник полезной нагрузки", - "capExf0": "На {{host}}{{user}} конфиденциальные данные сводятся в один архив.", - "capExf1": "Начинается их передача наружу через {{tool}}.", - "capExf2": "Данные прибывают в {{dest}}: они уже за пределами компании.", - "capExf3": "Блокировать передачу, отозвать доступ к {{dest}} и выяснить, кто может к ним добраться.", - "titleExf": "{{name}} выводит данные на {{to}}", - "scDefenses": "Защитные меры", - "scDisabled": "✕ отключено", - "scLogsCleared": "🗑 журналы очищены", - "dEvLog": "аудит-след", - "dEvEnf": "принудительное исполнение", - "capEv0": "На {{host}} атакующий начинает трогать то, что за ним следит.", - "capEv1": "{{what}} отключено: ещё одно наблюдение исчезло.", - "capEv2": "Журналы очищены: след его действий исчезает.", - "capEv2b": "С отключённым {{what}} хост слеп для атакующего.", - "capEv3": "Вернуть отключённые средства и сохранить оставшиеся журналы, пока они не исчезли.", - "titleEv": "Защитные меры отключены на {{to}}", - "scNormalUser": "обычный пользователь", - "scToken": "токен", - "dEvUac": "обход UAC", - "dEvToken": "похищен токен", - "dEvSuid": "злоупотребление setuid-бинарником", - "dEvSudo": "злоупотребление кэшем sudo", - "dEvExploit": "эксплуатация ядра", - "dEvDefault": "преодолен порог привилегий", - "capPe0": "На {{host}} сессия работает обычным пользователем.{{user}}", - "capPeUser": ", {{user}}", - "capPe1": "Он использует {{method}}, чтобы достичь более высокого уровня привилегий.", - "capPe2": "Команды теперь выполняются как {{account}}: полный контроль хоста.", - "capPe3": "Завершить эскалированную сессию и проверить, что мог задеть {{account}}.", - "titlePe": "Эскалация привилегий на {{to}} через {{method}}", - "alertRaised": "Событие создано", - "userExec": "Пользователь открыл вредоносный файл", - "softwareDeploy": "Программное обеспечение развёрнуто на хост", - "phishing": "Открыта фишинговая почта", - "processInjection": "Код внедрён в процесс", - "credDump": "Утечка учётных данных", - "dataDestruction": "Данные уничтожены", - "toolDownload": "Инструмент загружен и запущен", - "c2tunnel": "C2 через туннель", "scExec": "Выполнение", "scPayload": "→ вредоносный полезный груз", "capUe0": "На {{host}}{{user}} пользователь скачивает файл и открывает его.", @@ -6540,135 +6694,5 @@ "capCt1": "Полезная нагрузка спрятана в трафике {{proto}}.", "capCt2": "Команды и данные проходят границу невидимо, на {{proto}}.", "capCt3": "Оборвать туннель, заблокировать конечность и проверить, что прошло через него.", - "titleCt": "{{src}} протуннелил C2 через {{proto}} к {{to}}", - "netPerimeter": "Периметр", - "scDc": "Контроллер домена", - "scObject": "Изменённый объект", - "scChangedBy": "изменено", - "scHighRisk": "высокорисковое изменение", - "scTktAsk": "запрос билета", - "scTktUses": "перепроверено на {{n}} сервисов", - "scTerminal": "Терминал", - "scRunning": "…выполняется", - "scAmsiOff": "⚠ AMSI отключён", - "scConn": "TCP {{port}}", - "scShellOn": "$ обратный shell", - "scHypervisor": "Гипервизор", - "scGuestVm": "гостевая VM", - "scConfined": "заперта в госте", - "scEscaped": "вышла на хост", - "scBoundary": "граница гостя нарушена", - "scFeedAsk": "фид? {{ioc}}", - "scFeedBad": "ХУДО", - "scFeedHit": "Разведка: {{kind}}", - "scDroppedAtFw": "✕ отброшено на {{fw}}", - "scTrafficStops": "трафик здесь останавливается", - "scSigHits": "Попадания по сигнатуре", - "capIoc0": "{{src}} соединяется с {{ioc}}.", - "capIoc1": "Разведка о угрозах помечает: {{kind}}.", - "capIoc2": "{{ioc}} в стоп-листе: соединение оборвано.", - "capIoc3": "Заблокировать {{ioc}} на периметре и проверить, что уже ушло из сети.", - "titleIoc": "{{src}} достигает известного {{ioc}}", - "capPd0": "{{name}} шлёт {{sig}} на периметр.", - "capPd1": "{{fw}} совпал с сигнатурой и сработал.", - "capPd2": "Трафик отброшен: периметр выдержал.", - "capPd3": "Трафик проходит через {{fw}}: сигнал информативный.", - "capPd4": "Проверить сигнатуру и заблокировать источник, если он не прекратил.", - "titlePd": "{{sig}} заблокировано на {{fw}}", - "capAc0": "{{who}} изменяет {{what}} на {{host}}.", - "capAc1": "{{what}} модифицирован.", - "capAc2": "{{before}} → {{after}}.", - "capAc3": "Подтвердить, что это было спланировано, или откатить изменение {{who}}.", - "titleAc": "{{what}} изменено на {{host}}", - "capKb0": "{{src}} запрашивает билеты Kerberos у {{dc}}.", - "capKb1": "Полученный {{ticket}} — это {{kind}}.", - "capKb2": "Он повторно использован на {{services}}: DC принимает каждый раз.", - "capKb3": "Сбросить пароль krbtgt и просмотреть выданные билеты за 48 ч.", - "titleKb": "{{src}} подделывает Kerberos-билеты через {{dc}}", - "capPs0": "На {{host}} запускается скрипт с закодированным содержимым.", - "capPs1": "Он декодирует команду и отключает сенсор антивируса (AMSI).", - "capPs2": "Декодированная команда выполняется: это полезная нагрузка, не скрипт.", - "capPs2a": "Сначала отключают AMSI, затем декодированная команда выполняется незаметно.", - "capPs3": "Заблокировать хеш, поискать другие машины с тем же скриптом.", - "titlePs2": "Закодированный скрипт выполняется на {{host}}", - "capRs0": "На {{host}} процесс открывает сокет наружу.", - "capRs1": "Он переподключается к {{name}} на порт {{port}}: обратный shell.", - "capRs2": "Появляется приглашение: атакующий теперь может печатать команды на хосте.", - "capRs3": "Оборвать соединение, изолировать {{host}} и посмотреть, что было введено.", - "titleRs": "Обратный shell открыт на {{host}}", - "capVm0": "Гостевая VM {{guest}} запускает процесс с хост-доступом.", - "capVm1": "Он пытается пересечь границу гипервизора.", - "capVm2": "Процесс выполняется на хосте {{host}}: гость больше не клетка.", - "capVm3": "Паниковать гипервизор, сделать снапшот гостя и пересобрать.", - "titleVm": "Гость {{guest}} вырвался на {{host}}", - "listNew": "Новый", - "newAlertsCount_one": "{{count}} новый алерт", - "newAlertsCount_few": "{{count}} новых алерта", - "newAlertsCount_many": "{{count}} алертов", - "newAlertsCount_other": "{{count}} новых алертов", - "statTotal": "Всего", - "timPage": "Страница {{p}}/{{n}}", - "timPagePrev": "Предыдущая страница", - "timPageNext": "Следующая страница", - "newAlerts": "Новые алерты" - }, - "scExec": "Выполнение", - "scPayload": "→ вредоносный полезный груз", - "capUe0": "На {{host}}{{user}} пользователь скачивает файл и открывает его.", - "capUeUser": ", {{user}}", - "capUe1": "Файл открыт: {{file}} доверяется и выполняется.", - "capUe2": "{{app}} запускает дочерний процесс, который выполняет {{payload}}.", - "capUe3": "Поместить файл в карантин, заблокировать его хеш и проверить другие хосты, открывшие его.", - "titleUe": "{{file}} открыт на {{to}}", - "scDeploy": "Развёртывание", - "capSd0": "{{src}} разворачивает программное обеспечение на {{to}} по сети.", - "capSd1": "Используется {{tool}}: канал, который устанавливает без участия пользователя.", - "capSd2": "Пакет установлен на {{to}} и запускается вместе с ним.", - "capSd3": "Остановить развёртывание, удалить установленный компонент и проверить, что он делал.", - "titleSd": "Программное обеспечение развёрнуто с {{src}} на {{to}}", - "scAttachment": "вложение открыто", - "capPh0": "{{name}} отправляет фишинговое письмо в компанию.", - "capPh1": "Письмо попадает в почтовый ящик {{user}} и открывается.", - "capPh2": "Вложение выполняется: {{file}} запускается на машине.", - "capPh3": "Поместить письмо в карантин, заблокировать отправителя и удалить {{file}} с машины {{user}}.", - "titlePh": "Фишинговое письмо открыл {{user}} (от {{from}})", - "scInject": "Внедрение", - "scInside": "— код внутри доверенного процесса", - "capPi0": "На {{host}} запускается лоадер атакующего: {{injector}}.", - "capPi1": "Он внедряет код в доверенный процесс: {{victim}}.", - "capPi2": "{{victim}} теперь выполняет код атакующего со своими привилегиями.", - "capPi3": "Завершить внедрённый код, удалить лоадер и искать других жертв.", - "titlePi": "{{injector}} внедряет код в {{victim}}", - "scCred": "Хранилище учётных данных", - "scSecrets": "{{n}} секретов", - "scSecret": "секрет", - "scStolen": "✕ учётные данные похищены", - "capCd0": "На {{host}} инструмент начинает читать хранилище учётных данных.", - "capCd1": "Он открывает {{store}} и извлекает содержимое.", - "capCd2": "Пойманы {{n}} учётных данных: аккаунты, ключи и хеши.", - "capCd3": "Сменить все учётные данные хранилища и искать инструмент сброса.", - "titleCd": "{{store}} сброшен на {{host}}", - "scData": "Данные", - "scDataItem": "набор-{{i}}", - "scGone": "потеряно", - "scNoRecovery": "данные уничтожены", - "capDd0": "На {{host}} что-то начинает стирать данные, а не шифровать.", - "capDd1": "{{n}} наборов данных уничтожаются один за другим.", - "capDd2": "Данные удаляются в сыром виде: без записки, без выкупа, без возврата.", - "capDd3": "Остановить исходный процесс и восстановить остаток из офлайн-резервов.", - "titleDd": "Данные уничтожены на {{host}}", - "scDownload": "байты", - "scExecuted": "запущено", - "capTd0": "{{src}} поставляет инструмент на {{to}}.", - "capTd1": "Он скачивается в запись-доступную папку: {{folder}}.", - "capTd2": "Файл запускается: {{tool}} теперь работает.", - "capTd3": "Удалить инструмент, заблокировать его хеш и проверить, какие хосты его запустили.", - "titleTd": "{{src}} размещает инструмент на {{to}}", - "scTunnel": "скрыто в трафике {{proto}}", - "scTunneled": "Протуннелировано байт", - "capCt0": "{{src}} общается с {{to}} по виду обычному протоколу.", - "capCt1": "Полезная нагрузка спрятана в трафике {{proto}}.", - "capCt2": "Команды и данные проходят границу невидимо, на {{proto}}.", - "capCt3": "Оборвать туннель, заблокировать конечность и проверить, что прошло через него.", - "titleCt": "{{src}} протуннелил C2 через {{proto}} к {{to}}" + "titleCt": "{{src}} протуннелил C2 через {{proto}} к {{to}}" }