Documentation
¶
Index ¶
- Constants
- Variables
- func CreateProject(db *orm.DB, id, name, plainSecret string) error
- func EnsureRole(rbacSvc *rbac.Service, authMod *authority.Module, projectID, roleID string, ...) error
- func IssueAuthToken(rbacSvc *rbac.Service, secret []byte, projectID, userID string) (string, error)
- func MigrateProjects(conn ddl.Execer, ddlCompiler ddl.Compiler) error
- func NewLocalAuth(db *orm.DB, ids model.IDGenerator) (*authority.Module, *rbac.Service, error)
- func NewLocalAuthWithScenarios(db *orm.DB, ids model.IDGenerator, scenarios []local.Scenario) (*authority.Module, *rbac.Service, error)
- func NewProductionAuth(db *orm.DB, ids model.IDGenerator) (*authority.Module, *rbac.Service, error)
- func VerifyProjectSecret(db *orm.DB, projectID, plainSecret string) (bool, error)
- type Backend
- type Project
- type ProjectList
- func (s *ProjectList) Append() model.Fielder
- func (s *ProjectList) At(i int) model.Fielder
- func (s *ProjectList) DecodeFields(_ model.FieldReader)
- func (s *ProjectList) EncodeFields(_ model.FieldWriter)
- func (s *ProjectList) IsNil() bool
- func (s *ProjectList) Len() int
- func (s *ProjectList) Pointers() []any
- func (s *ProjectList) Schema() []model.Field
Constants ¶
const ( CookieSession = "iam_session" TTLSession = 86400 * 7 EnvGoogleClientID = "GOOGLE_CLIENT_ID" EnvGoogleClientSecret = "GOOGLE_CLIENT_SECRET" EnvGoogleRedirectURL = "GOOGLE_REDIRECT_URL" EnvJWTSecret = "JWT_SECRET" // SSOCookieDomain es el dominio padre bajo el que la cookie de // identidad se comparte entre subdominios (ver ARCHITECTURE.md §7): // iam.velty.cl, misitio.velty.cl, etc. leen la MISMA sesión. SSOCookieDomain = ".velty.cl" // SSOSessionTTL: 7 días — ver ARCHITECTURE.md §7. SSOSessionTTL = 86400 * 7 )
const DefaultAuthTokenTTL = 30 * 60 // 30 minutos — ver ARCHITECTURE.md §6.3
Variables ¶
var ErrProjectNotFound = fmt.Err("project", "not", "found")
ErrProjectNotFound reports that a project id has no matching row.
var LocalJWTSecret = []byte("iam-local-dev-secret-do-not-use-in-prod")
LocalJWTSecret es el secreto HS256 fijo de desarrollo/tests, donde no hay variables de entorno de producción. Nunca se usa en producción: NewProductionAuth exige EnvJWTSecret y falla rápido si falta.
var LocalScenarios = []local.Scenario{ {ID: user.SubjectID("local-admin"), Name: "Admin Local", Email: "admin@iam.local"}, {ID: user.SubjectID("local-viewer"), Name: "Viewer Local", Email: "viewer@iam.local"}, }
LocalScenarios son identidades de desarrollo determinísticas para probar iam en aislamiento, sin secretos de Google. Sin roles asignados: cada test decide qué rol/permiso probar (ver bootstrap_test.go).
var ProjectModel = model.Definition{ Name: "project", Fields: model.Fields{ {Name: "id", Type: model.Text(), DB: &model.FieldDB{PK: true}}, {Name: "name", Type: model.Text()}, {Name: "client_secret_hash", Type: model.Text()}, {Name: "created_at", Type: model.Int()}, }, }
Project is iam's own concept, not rbac's: rbac knows roles/permissions scoped by project_id, but has no notion of an application authenticating itself to ask for a token — that credential belongs here.
var Project_ = struct { Id string Name string ClientSecretHash string CreatedAt string }{ Id: "id", Name: "name", ClientSecretHash: "client_secret_hash", CreatedAt: "created_at", }
Functions ¶
func CreateProject ¶ added in v0.0.6
CreateProject registra un proyecto nuevo y devuelve el client_secret EN CLARO una sola vez — no se puede recuperar después, solo regenerar.
func EnsureRole ¶
func EnsureRole(rbacSvc *rbac.Service, authMod *authority.Module, projectID, roleID string, roleCode model.RoleCode, roleName, roleDescription string, emails []string) error
EnsureRole crea el rol (si no existe) y lo asigna de forma idempotente a cada email de la lista, creando el usuario en auth si todavía no existe. No crea ni asigna permisos: adjuntar permisos al rol es responsabilidad de quien llama — cada app declara su propia política (ver ARCHITECTURE.md §1: "Policy belongs to the consumer" de tinywasm/rbac).
func IssueAuthToken ¶ added in v0.0.6
IssueAuthToken firma un token de autorizacion project-scoped para userID, usando el SessionTTL mas restrictivo entre sus roles en projectID (0 => DefaultAuthTokenTTL). secret es el mismo secreto HS256 que usa el resto de la sesion de iam. Aud lleva projectID, Scope lleva los codigos de rol — vocabulario JWT estandar, ver ARCHITECTURE.md §6.2.
func MigrateProjects ¶ added in v0.0.19
MigrateProjects reconciles the schema this service owns (Project).
Deliberately not called from NewProductionBackend: schema reconciliation is deploy-time work. Doing it per process start cost ~10 D1 round trips on every isolate cold start (8.5–10.4 s measured). cmd/migrate calls this once, from CI.
func NewLocalAuth ¶
NewLocalAuth arma el motor de identidad+RBAC para desarrollo, sin Google.
func NewLocalAuthWithScenarios ¶
func NewLocalAuthWithScenarios(db *orm.DB, ids model.IDGenerator, scenarios []local.Scenario) (*authority.Module, *rbac.Service, error)
NewLocalAuthWithScenarios permite a los tests inyectar escenarios propios.
func NewProductionAuth ¶
NewProductionAuth arma el motor de identidad+RBAC para producción (Google OAuth). Lee env directamente via env.Get (auto-tag !wasm=os+.env, wasm=context.env); este paquete nunca importa "os" directamente (ver AGENTS.md Restricción #3). Falla rápido si falta cualquier variable: arrancar con OAuth roto en silencio es peor que no arrancar. No crea roles ni permisos — eso es política de cada app consumidora (ver bootstrap.go para el mecanismo genérico de asignación por email).
Types ¶
type Backend ¶ added in v0.0.6
type Backend struct {
Auth *authority.Module
RBAC *rbac.Service
DB *orm.DB
// JWTSecret firma tanto la cookie de identidad (Etapa 4) como el token
// de autorización project-scoped (Etapa 3, ver routes.Token) — un solo
// secreto HS256 para todo iam.
JWTSecret []byte
}
Backend agrupa los módulos de dominio que comparten la misma base y generador de IDs — es el único lugar donde se orquesta NewProductionAuth/NewLocalAuth, así que tanto edge/main.go (D1 real) como web/server.go (memoria) y los tests lo llaman con la DB inyectada, y la lógica se prueba una vez.
func NewLocalBackend ¶ added in v0.0.6
NewLocalBackend inicializa el mismo motor para desarrollo, sin Google ni dominio de cookie compartido (ver NewLocalAuth — !wasm only, igual que esta función: nunca compila dentro del Worker de producción).
func NewProductionBackend ¶ added in v0.0.6
NewProductionBackend inicializa identidad, RBAC y el esquema de proyectos para producción (Google OAuth + cookie SSO cross-dominio).
type Project ¶ added in v0.0.6
func ReadOneProject ¶ added in v0.0.6
func (*Project) DecodeFields ¶ added in v0.0.6
func (m *Project) DecodeFields(r model.FieldReader)
func (*Project) EncodeFields ¶ added in v0.0.6
func (m *Project) EncodeFields(w model.FieldWriter)
type ProjectList ¶ added in v0.0.6
type ProjectList []*Project
func ReadAllProject ¶ added in v0.0.6
func ReadAllProject(qb *orm.QB) (ProjectList, error)
func (*ProjectList) Append ¶ added in v0.0.6
func (s *ProjectList) Append() model.Fielder
func (*ProjectList) DecodeFields ¶ added in v0.0.6
func (s *ProjectList) DecodeFields(_ model.FieldReader)
func (*ProjectList) EncodeFields ¶ added in v0.0.6
func (s *ProjectList) EncodeFields(_ model.FieldWriter)
func (*ProjectList) IsNil ¶ added in v0.0.6
func (s *ProjectList) IsNil() bool
func (*ProjectList) Len ¶ added in v0.0.6
func (s *ProjectList) Len() int
func (*ProjectList) Pointers ¶ added in v0.0.6
func (s *ProjectList) Pointers() []any
func (*ProjectList) Schema ¶ added in v0.0.6
func (s *ProjectList) Schema() []model.Field