buildpacks / spec

Specification for Cloud Native Buildpacks
https://buildpacks.io
Apache License 2.0
251 stars 69 forks source link

[RFC 0076] Require `CNB_{USER,GROUP}_SID` instead of `CNB_{USER,GROUP}_ID` on windows stack images #129

Open ekcasey opened 4 years ago

ekcasey commented 4 years ago

RFC 0076 https://github.com/buildpacks/rfcs/pull/133

Motivating context: https://github.com/buildpacks/lifecycle/issues/343

02/17/2021 - Updated to reflect the result of the RFC above

micahyoung commented 3 years ago

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==
ekcasey commented 3 years ago

@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?

micahyoung commented 3 years ago

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

ekcasey commented 3 years ago

@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).

micahyoung commented 3 years ago

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/

ekcasey commented 3 years ago

@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.

micahyoung commented 3 years ago

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.