Documentation
¶
Overview ¶
Package model holds postern's domain types.
S2'de bu tipler config'den elle kuruluyordu; S3'ten beri veritabanından geliyorlar (şema bu alanların birebir karşılığı). Kararları veren kod model tiplerine baktığı için, kaynağın değişmesi policy'yi etkilemedi — motorun SQLite'tan PostgreSQL'e geçmesi de bu pakete dokunmadı.
Index ¶
Constants ¶
const UnknownGroup = "unknown"
* UnknownGroup, kaynağın CEVAP VERDİĞİ ama hiçbir grup söylemediği * kullanıcıların düştüğü grup. * * ⚠️ ÇÖZÜLDÜ AMA BOŞ ≠ ÇÖZÜLEMEDİ. Bu grup YALNIZCA kaynak "bu kişiyi * tanıyorum ve hiçbir grupta değil" dediğinde uygulanır. Dizin cevap * veremediğinde ya da kullanıcıyı hiç bulamadığında uygulanmaz — o iki * hâlde hiçbir şey bilinmiyor demektir ve bir arızayı yetkiye çevirmek, * default-deny'ın tam tersi olurdu. * * Var olma sebebi somut: grup claim'i göndermeyen bir IdP'de hiç kimse * hiçbir role eşleşmiyor, ProvisionUser hesabı AÇMIYOR ve kullanıcı * kapıda kalıyor — yöneticinin elinde onu düzeltecek bir tutamak bile * olmadan. Bu grup o tutamağı veriyor: yönetici `unknown`'ı bir role * eşler, kullanıcı içeri girer ve doğru grubuna elle atanır.
Variables ¶
This section is empty.
Functions ¶
func ResolvedGroups ¶
* ResolvedGroups, çözülmüş bir grup listesini role çevrilmeye hazırlar. * * ⚠️ YALNIZCA PRESENCE=PRESENT olan çağrı noktalarından çağrılmalı. * İmzası bunu zorlayamıyor (bir []string alıyor), o yüzden kural her * çağrı yerinde yazılı: "kaynak cevap verdi" bilgisi orada duruyor, * burada değil.
func ValidOSUserName ¶
ValidOSUserName reports whether name may be used as a target account.
Types ¶
type Role ¶
Role, bir hedef kümesine erişim yetkisi.
S3 şemasında roles + role_targets tablolarının karşılığı.
type Session ¶
type Session struct {
// ID, record.NewSessionID()'nin ürettiği değer. Kayıt dosyasının adı
// da bu olduğu için, denetim kaydı ile .cast dosyası arasındaki bağ
// tek bir alanla kuruluyor.
ID string
// User ve Target, id değil AD tutar. Denetim kaydını okuyan insan
// "hangi kullanıcı" diye sorduğunda cevabın bir JOIN'e ihtiyacı olmasın.
User string
Target string
// OSUser, oturumun AÇILDIĞI hesap.
//
// users.os_user'ın kopyası gibi görünür ama değildir: policy o an
// başka bir hesaba karar vermiş olabilir ve kullanıcının bugünkü
// os_user'ı o günkü kararı değiştirmemeli. Denetim, kaydın alındığı
// andaki gerçeği saklar.
OSUser string
// SrcIP, kullanıcının bastion'a bağlandığı adres.
SrcIP string
StartedAt time.Time
// EndedAt sıfır değerse oturum hâlâ açık (şemada NULL).
EndedAt time.Time
// RecordingPath, .cast dosyasının yolu. Kayıt açılamadıysa boş —
// ama o durumda oturum zaten reddedilmiş olmalı (S1.8 kararı).
RecordingPath string
}
Session, açılmış bir oturumun denetim kaydı.
S3 şemasında sessions tablosu. Bu kayıt oturumdan DAHA UZUN yaşar: kullanıcı ya da hedef sonradan silinse bile "kim, nereye, ne zaman girdi" sorusunun cevabı durmak zorunda.
type Target ¶
type Target struct {
Name string
Host string
Port int
HostKey string
// Labels, operatörün iliştirdiği key=value notları ("env=prod").
//
// ⚠️ YETKİ DEĞİL: erişimi rol → hedef bağı veriyor. Etiket yalnızca
// hedefleri gruplayıp bulmak için — etiketten yetki türetmek,
// etiket ekleyebilen herkese yetki dağıtmak olurdu.
//
// Yalnızca LİSTELEME yollarında dolu (store.Targets). Oturum açma
// yolundaki tekil okuma bunu çekmiyor: her bağlantıda ikinci bir
// sorgu, hiç kullanılmayan bir alan için.
Labels map[string]string
}
type TargetFacts ¶
type TargetFacts struct {
// ServerVersion, sunucunun kendi afişi: "SSH-2.0-OpenSSH_9.6p1 Debian-3".
ServerVersion string
// HostKeyType, pinlenmiş anahtarın türü (ssh-ed25519 …).
HostKeyType string
// LastSeenAt, son BAŞARILI bağlantı. Sıfır ise hiç bağlanılmadı.
LastSeenAt time.Time
// ConnectMS, o bağlantının el sıkışma süresi.
ConnectMS int
// LastErrorAt/LastError, son BAŞARISIZ deneme. Başarıyı silmiyor.
LastErrorAt time.Time
LastError string
// Probe, yalnızca target_probe.enabled ile dolar — yani hedefte
// komut çalıştırıldıysa. ProbedAt sıfırsa hedefe hiç dokunulmadı.
//
// İç içe duruyor ki paneli çizen de, koda bakan da "bu satırı
// öğrenmek için makineye dokunduk mu" sorusunu tek bakışta
// cevaplayabilsin.
Probe TargetProbe
ProbedAt time.Time
}
TargetFacts, hedefe BAĞLANIRKEN öğrenilenler.
⚠️ Yapılandırma değil GÖZLEM: Target operatörün yazdığını, bu yapı makinenin söylediğini tutuyor. Ve içeriği yalnızca el sıkışmadan geliyor — hedefte komut çalıştırıp uname/os-release okumak daha fazlasını verirdi ama postern kullanıcının oturumu dışında hedefte iş çalıştırmaz.
type TargetProbe ¶
type TargetProbe struct {
// Kernel, `uname -srm` çıktısı.
Kernel string
// OSName, /etc/os-release içindeki PRETTY_NAME (yoksa NAME).
OSName string
}
TargetProbe, hedefte KOMUT ÇALIŞTIRARAK öğrenilenler.
⚠️ TargetFacts'ten AYRI TUTULUYOR ve bu ayrım kasıtlı: TargetFacts'in içeriği el sıkışmadan gelir ve postern hedefte hiçbir şey çalıştırmadan öğrenilir. Buradakiler ise ancak target_probe.enabled ile, hedefte komut koşturularak elde ediliyor. İkisini aynı yapıya koymak, panele bakan operatörün "bunu öğrenmek için makineye dokunduk mu" sorusunu cevapsız bırakırdı.
type User ¶
type User struct {
// Name, postern kullanıcı adı ("yigit"). auth.go'nun doğruladığı ve
// Permissions'a koyduğu değer.
Name string
// OSUser, kişinin hedeflerdeki VARSAYILAN hesabı. İstek boş geldiğinde
// principal bu olur.
//
// S3 şemasında users.os_user (NOT NULL) — kişiye özel, paylaşılmaz.
// Driver 1'in özü bu alan: herkes hedefe kendi adıyla düşüyor.
OSUser string
// Roles, kişinin sahip olduğu roller. Hedef erişimi rollerden gelir.
Roles []Role
// SSOOnly true ise bu kullanıcı YALNIZCA kimlik sağlayıcı üzerinden
// girebilir; public key ile girişi reddedilir.
//
// IdP'den otomatik oluşan (JIT) kullanıcılar böyle doğar: erişimleri
// IdP'de kapatılınca gerçekten bitsin ve rolleri her girişte
// tazelensin diye. Elle oluşturulan servis hesapları false kalır.
SSOOnly bool
/*
* DirBound, hesabın bir DİZİN kimliğine bağlı olduğu.
*
* ⚠️ Oturum açılışında dizine yeniden sorulup sorulmayacağının
* DOĞRU koşulu bu — SSOOnly değil. Ölçüldü: yetkisi dizinden gelen
* bir yönetici (admin_via='group') sso_only=false ile duruyordu,
* yani dizinde kapatılsa bile anahtarıyla oturum açardı.
*/
DirBound bool
// Admin, uygulama YÖNETİM yetkisi (kullanıcı/rol/hedef değiştirme,
// web'deki yönetim sayfaları). Hedef erişimiyle ilgisi yok: admin
// olmayan biri terminale girebilir, admin olan biri rolü yoksa hiçbir
// hedefe giremez. İki eksen bilerek ayrık.
Admin bool
}
User, bastion'da kimliği doğrulanmış kişi.