[{"data":1,"prerenderedAt":542},["ShallowReactive",2],{"nav-stories":3,"footer-stories":61,"project-veil-auth":74},[4,16,25,34,43,52],{"id":5,"color":6,"extension":7,"image":8,"label":9,"link":10,"meta":11,"order":12,"stem":13,"text":14,"__hash__":15},"stories\u002Fstories\u002F01-data-center.yml",null,"yml","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1558494949-ef010cbdcc31?w=1080","DATA_CENTER","https:\u002F\u002Fx.com\u002Fabbeytetteh_",{},1,"stories\u002F01-data-center","Racking new servers. 40gbit backbone online.","0QUZQbaANhdO8WemZxkDdO7vbVopfnynHtH9FxBZb_w",{"id":17,"color":6,"extension":7,"image":18,"label":19,"link":6,"meta":20,"order":21,"stem":22,"text":23,"__hash__":24},"stories\u002Fstories\u002F02-thoughts.yml","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1498050108023-c5249f4df085?w=1080","THOUGHTS",{},2,"stories\u002F02-thoughts","Late night bug hunting. Found the memory leak.","Gd1am954aasY6HRHD7hCtOuessXb6zYZ8iizS501ICg",{"id":26,"color":27,"extension":7,"image":6,"label":28,"link":6,"meta":29,"order":30,"stem":31,"text":32,"__hash__":33},"stories\u002Fstories\u002F03-coding.yml","#3b82f6","CODING",{},3,"stories\u002F03-coding","Just thinking about how much easier life is with Swarm.","vLAyiGUPtlXB2SHa5KM_U2AaK4QkG3Og85UEUE7qzgM",{"id":35,"color":6,"extension":7,"image":36,"label":37,"link":6,"meta":38,"order":39,"stem":40,"text":41,"__hash__":42},"stories\u002Fstories\u002F04-update.yml","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1591799264318-7e6ef8ddb7ea?w=1080","UPDATE",{},4,"stories\u002F04-update","New cluster nodes arrived. Prepping for installation.","kyT60N5C6Re_jMonZbgNy0PbQhzXmUWxDbD0D_v43ts",{"id":44,"color":45,"extension":7,"image":6,"label":46,"link":6,"meta":47,"order":48,"stem":49,"text":50,"__hash__":51},"stories\u002Fstories\u002F05-setup.yml","#86868b","SETUP",{},5,"stories\u002F05-setup","Optimizing the telemetry pipeline for 1M req\u002Fs.","cPOBkzoyXsCmPgRO2d80Hj3vm4MP-6nAejtlQ5iuSzw",{"id":53,"color":6,"extension":7,"image":54,"label":55,"link":6,"meta":56,"order":57,"stem":58,"text":59,"__hash__":60},"stories\u002Fstories\u002F06-travel.yml","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1560969184-10fe8719e047?w=1080","TRAVEL",{},6,"stories\u002F06-travel","Travel log — system architecture workshop in Berlin.","jnOxerdF6usAIHdR35Z-opx0LJAy9kZluXnZhtz62Z0",[62,64,66,68,70,72],{"id":5,"color":6,"extension":7,"image":8,"label":9,"link":10,"meta":63,"order":12,"stem":13,"text":14,"__hash__":15},{},{"id":17,"color":6,"extension":7,"image":18,"label":19,"link":6,"meta":65,"order":21,"stem":22,"text":23,"__hash__":24},{},{"id":26,"color":27,"extension":7,"image":6,"label":28,"link":6,"meta":67,"order":30,"stem":31,"text":32,"__hash__":33},{},{"id":35,"color":6,"extension":7,"image":36,"label":37,"link":6,"meta":69,"order":39,"stem":40,"text":41,"__hash__":42},{},{"id":44,"color":45,"extension":7,"image":6,"label":46,"link":6,"meta":71,"order":48,"stem":49,"text":50,"__hash__":51},{},{"id":53,"color":6,"extension":7,"image":54,"label":55,"link":6,"meta":73,"order":57,"stem":58,"text":59,"__hash__":60},{},{"id":75,"title":76,"body":77,"description":531,"extension":532,"hash":533,"liveUrl":6,"meta":534,"navigation":365,"order":362,"path":535,"rackBay":6,"rackStatus":6,"region":536,"seo":537,"stem":538,"thumbnail":539,"vault":540,"__hash__":541},"projects\u002Fprojects\u002Fveil-auth.md","Veil Auth",{"type":78,"value":79,"toc":525},"minimark",[80,84,89,92,500,504,507,511,514,518,521],[81,82,83],"p",{},"Veil Auth is the identity and access management service powering the administrative interfaces across the cluster. It issues short-lived JWTs, scoped API tokens for service-to-service calls, and enforces biometric second-factor for privileged operations.",[85,86,88],"h2",{"id":87},"token-architecture","Token Architecture",[81,90,91],{},"Access tokens are valid for 15 minutes. Refresh tokens are stored as opaque references in Redis with a 7-day TTL. Revoking a refresh token is an O(1) operation — delete the Redis key.",[93,94,99],"pre",{"className":95,"code":96,"language":97,"meta":98,"style":98},"language-go shiki shiki-themes vitesse-light","func (s *TokenService) Issue(ctx context.Context, subject string, scopes []string) (*TokenPair, error) {\n    claims := jwt.MapClaims{\n        \"sub\":    subject,\n        \"scopes\": scopes,\n        \"exp\":    time.Now().Add(15 * time.Minute).Unix(),\n        \"jti\":    uuid.New().String(),\n    }\n    access, _ := s.key.Sign(claims)\n\n    refreshID := uuid.New().String()\n    s.redis.SetEx(ctx, \"refresh:\"+refreshID, subject, 7*24*time.Hour)\n\n    return &TokenPair{Access: access, RefreshID: refreshID}, nil\n}\n","go","",[100,101,102,187,206,228,243,294,320,326,360,367,389,451,456,494],"code",{"__ignoreMap":98},[103,104,106,110,114,118,122,126,129,133,136,139,142,145,148,151,154,157,159,162,165,168,170,172,174,177,179,182,184],"span",{"class":105,"line":12},"line",[103,107,109],{"class":108},"sbBg2","func",[103,111,113],{"class":112},"sYZai"," (",[103,115,117],{"class":116},"svycV","s ",[103,119,121],{"class":120},"si04Y","*",[103,123,125],{"class":124},"sUxyF","TokenService",[103,127,128],{"class":112},")",[103,130,132],{"class":131},"sySUi"," Issue",[103,134,135],{"class":112},"(",[103,137,138],{"class":116},"ctx",[103,140,141],{"class":124}," context",[103,143,144],{"class":112},".",[103,146,147],{"class":124},"Context",[103,149,150],{"class":112},",",[103,152,153],{"class":116}," subject",[103,155,156],{"class":120}," string",[103,158,150],{"class":112},[103,160,161],{"class":116}," scopes",[103,163,164],{"class":112}," []",[103,166,167],{"class":120},"string",[103,169,128],{"class":112},[103,171,113],{"class":112},[103,173,121],{"class":120},[103,175,176],{"class":124},"TokenPair",[103,178,150],{"class":112},[103,180,181],{"class":120}," error",[103,183,128],{"class":112},[103,185,186],{"class":112}," {\n",[103,188,189,192,195,198,200,203],{"class":105,"line":21},[103,190,191],{"class":116},"    claims",[103,193,194],{"class":112}," :=",[103,196,197],{"class":124}," jwt",[103,199,144],{"class":112},[103,201,202],{"class":124},"MapClaims",[103,204,205],{"class":112},"{\n",[103,207,208,212,216,219,222,225],{"class":105,"line":30},[103,209,211],{"class":210},"sSP4y","        \"",[103,213,215],{"class":214},"spphp","sub",[103,217,218],{"class":210},"\"",[103,220,221],{"class":112},":",[103,223,224],{"class":116},"    subject",[103,226,227],{"class":112},",\n",[103,229,230,232,235,237,239,241],{"class":105,"line":39},[103,231,211],{"class":210},[103,233,234],{"class":214},"scopes",[103,236,218],{"class":210},[103,238,221],{"class":112},[103,240,161],{"class":116},[103,242,227],{"class":112},[103,244,245,247,250,252,254,257,259,262,265,268,270,274,277,280,282,285,288,291],{"class":105,"line":48},[103,246,211],{"class":210},[103,248,249],{"class":214},"exp",[103,251,218],{"class":210},[103,253,221],{"class":112},[103,255,256],{"class":116},"    time",[103,258,144],{"class":112},[103,260,261],{"class":131},"Now",[103,263,264],{"class":112},"().",[103,266,267],{"class":131},"Add",[103,269,135],{"class":112},[103,271,273],{"class":272},"s-TwI","15",[103,275,276],{"class":120}," *",[103,278,279],{"class":116}," time",[103,281,144],{"class":112},[103,283,284],{"class":116},"Minute",[103,286,287],{"class":112},").",[103,289,290],{"class":131},"Unix",[103,292,293],{"class":112},"(),\n",[103,295,296,298,301,303,305,308,310,313,315,318],{"class":105,"line":57},[103,297,211],{"class":210},[103,299,300],{"class":214},"jti",[103,302,218],{"class":210},[103,304,221],{"class":112},[103,306,307],{"class":116},"    uuid",[103,309,144],{"class":112},[103,311,312],{"class":131},"New",[103,314,264],{"class":112},[103,316,317],{"class":131},"String",[103,319,293],{"class":112},[103,321,323],{"class":105,"line":322},7,[103,324,325],{"class":112},"    }\n",[103,327,329,332,334,337,339,342,344,347,349,352,354,357],{"class":105,"line":328},8,[103,330,331],{"class":116},"    access",[103,333,150],{"class":112},[103,335,336],{"class":116}," _",[103,338,194],{"class":112},[103,340,341],{"class":116}," s",[103,343,144],{"class":112},[103,345,346],{"class":116},"key",[103,348,144],{"class":112},[103,350,351],{"class":131},"Sign",[103,353,135],{"class":112},[103,355,356],{"class":116},"claims",[103,358,359],{"class":112},")\n",[103,361,363],{"class":105,"line":362},9,[103,364,366],{"emptyLinePlaceholder":365},true,"\n",[103,368,370,373,375,378,380,382,384,386],{"class":105,"line":369},10,[103,371,372],{"class":116},"    refreshID",[103,374,194],{"class":112},[103,376,377],{"class":116}," uuid",[103,379,144],{"class":112},[103,381,312],{"class":131},[103,383,264],{"class":112},[103,385,317],{"class":131},[103,387,388],{"class":112},"()\n",[103,390,392,395,397,400,402,405,407,409,411,414,417,419,422,425,427,429,431,434,436,439,441,444,446,449],{"class":105,"line":391},11,[103,393,394],{"class":116},"    s",[103,396,144],{"class":112},[103,398,399],{"class":116},"redis",[103,401,144],{"class":112},[103,403,404],{"class":131},"SetEx",[103,406,135],{"class":112},[103,408,138],{"class":116},[103,410,150],{"class":112},[103,412,413],{"class":210}," \"",[103,415,416],{"class":214},"refresh:",[103,418,218],{"class":210},[103,420,421],{"class":120},"+",[103,423,424],{"class":116},"refreshID",[103,426,150],{"class":112},[103,428,153],{"class":116},[103,430,150],{"class":112},[103,432,433],{"class":272}," 7",[103,435,121],{"class":120},[103,437,438],{"class":272},"24",[103,440,121],{"class":120},[103,442,443],{"class":116},"time",[103,445,144],{"class":112},[103,447,448],{"class":116},"Hour",[103,450,359],{"class":112},[103,452,454],{"class":105,"line":453},12,[103,455,366],{"emptyLinePlaceholder":365},[103,457,459,462,465,467,470,473,475,478,480,483,485,488,491],{"class":105,"line":458},13,[103,460,461],{"class":108},"    return",[103,463,464],{"class":120}," &",[103,466,176],{"class":124},[103,468,469],{"class":112},"{",[103,471,472],{"class":116},"Access",[103,474,221],{"class":112},[103,476,477],{"class":116}," access",[103,479,150],{"class":112},[103,481,482],{"class":116}," RefreshID",[103,484,221],{"class":112},[103,486,487],{"class":116}," refreshID",[103,489,490],{"class":112},"},",[103,492,493],{"class":120}," nil\n",[103,495,497],{"class":105,"line":496},14,[103,498,499],{"class":112},"}\n",[85,501,503],{"id":502},"biometric-second-factor","Biometric Second Factor",[81,505,506],{},"WebAuthn handles the biometric flow. The server stores credential public keys, never any biometric data. Browser passkeys and hardware security keys are both supported. The fallback for non-WebAuthn clients is TOTP.",[85,508,510],{"id":509},"audit-log","Audit Log",[81,512,513],{},"Every authentication event, token issue, and access denial is written to an append-only audit log in Postgres with a cryptographic hash chain — each record includes the hash of the previous record, making retroactive tampering detectable.",[85,515,517],{"id":516},"status","Status",[81,519,520],{},"Running in production, protecting 6 administrative interfaces. Planning a self-service credential management UI for the next release.",[522,523,524],"style",{},"html pre.shiki code .sbBg2, html code.shiki .sbBg2{--shiki-default:#1E754F}html pre.shiki code .sYZai, html code.shiki .sYZai{--shiki-default:#999999}html pre.shiki code .svycV, html code.shiki .svycV{--shiki-default:#B07D48}html pre.shiki code .si04Y, html code.shiki .si04Y{--shiki-default:#AB5959}html pre.shiki code .sUxyF, html code.shiki .sUxyF{--shiki-default:#2E8F82}html pre.shiki code .sySUi, html code.shiki .sySUi{--shiki-default:#59873A}html pre.shiki code .sSP4y, html code.shiki .sSP4y{--shiki-default:#B5695977}html pre.shiki code .spphp, html code.shiki .spphp{--shiki-default:#B56959}html pre.shiki code .s-TwI, html code.shiki .s-TwI{--shiki-default:#2F798A}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":98,"searchDepth":21,"depth":21,"links":526},[527,528,529,530],{"id":87,"depth":21,"text":88},{"id":502,"depth":21,"text":503},{"id":509,"depth":21,"text":510},{"id":516,"depth":21,"text":517},"Zero-trust identity layer with JWT-based authentication, role-scoped API tokens, and biometric second factor for administrative consoles.","md","Y5Z6A7",{},"\u002Fprojects\u002Fveil-auth","CA-CENTRAL-1",{"title":76,"description":531},"projects\u002Fveil-auth","\u002Fimages\u002Fthumbnails\u002Fveil-auth.png",false,"3RnHwxVVupReRkyUAJhnBTtaDsZ_Q9PgFtbZ1leF9nA",1779361989391]