spec
spec copied to clipboard
[RFC 0076] Require `CNB_{USER,GROUP}_SID` instead of `CNB_{USER,GROUP}_ID` on windows stack images
RFC 0076 https://github.com/buildpacks/rfcs/pull/133
- Replace CNB_USER_ID and CNB_GROUP_ID with CNB_USER_SID and CNB_GROUP_SID on windows stack images
- Replace
-uid
and-gid
flags with-usid
and-gsid
flags for builds in windows environments
Motivating context: https://github.com/buildpacks/lifecycle/issues/343
02/17/2021 - Updated to reflect the result of the RFC above
After some digging, it appears there are no straight forward, cross-platform tools for converting SDDL to the binary format used as the header["MSWINDOWS.rawsd"]
.
The golang implementation calls the Windows API syscall to do convert it: source
Wine has an implementation but that would be a heavy-weight dependency and non-trivial to port to golang: source
I feel like our best bet may be to require to the format of CNB_SECURITY_DESCRIPTOR
to be the exact base64-encoded binary format of the MSWINDOWS.rawsd
header value. We could potentially provide a tool or powershell example, which runs on Windows and calls the Windows APIs, to convert it.
Which in the image config, would look like:
"config":{
"Env":[
"CNB_SECURITY_DESCRIPTOR= AQAAgBQAAAAkAAAAAAAAAAAAAAABAgAAAAAABSAAAAAgAgAAAQIAAAAAAAUgAAAAIAIAAA=="
]
}
Which would be generated with:
# for owner: BUILTIN/Administrators group: BUILTIN/Administrators
$sddlValue="O:BAG:BA"
$sddl = (ConvertFrom-SddlString $sddlValue)
$sddlBytes = [byte[]]::New($sddl.RawDescriptor.BinaryLength)
$sddl.RawDescriptor.GetBinaryForm($sddlBytes, 0)
[Convert]::ToBase64String($sddlBytes)
# => AQAAgBQAAAAkAAAAAAAAAAAAAAABAgAAAAAABSAAAAAgAgAAAQIAAAAAAAUgAAAAIAIAAA==
@micahyoung Do we need a cross-platform solution for this? We will only need to convert the string to the binary format on windows right, and therefore we can use the golang implementation?
If I recall, I thought create-builder
~~and package-buildpack
~~ sets pack-owned directories on the image which would have these permissions. I'll double-check though.
If this was only needed for lifecycle, we'd be fine with Windows-only though.
Update: here's the spot I was thinking of: https://github.com/buildpacks/pack/blob/96d1cdf9e98b4e9adfdb020c0bb253573a3917a5/internal/builder/builder.go#L541
@micahyoung good point, I was only thinking about the lifecycle/spec use case. I forgot that the platform reads and uses these env vars. create-builder
needs to set file ownership (package-buildpack
should not because he stack and therefore the user is unknown at the time of packaging).
The binary format is documented and we could potentially invest the time in implement a golang encoder. It would likely have to move out the timeline on this issue however.
There's a couple other C implementations I want to check out as well, though neither seems to have existing golang wrappers ... https://www.samba.org/samba/docs/current/man-html/sharesec.1.html
https://sourceforge.net/projects/ntfs-3g/
@micahyoung Given that this isn't perfectly straight forward, it is probably worth doing a proof-of-concept before committing to a strategy in the spec. I am going to reschedule this from platform API 0.5 to 0.6 to give us more time to explore options.
Good call. I feel user-friendly SDDL format (CNB_SECURITY_DESCRIPTOR="O:BAG:BA"
) is ideal so I'll keep hacking around at something that can process that into the header rawsd
format.