Documentation
¶
Overview ¶
Package distribution inspects and prepares local iOS release-testing artifacts. It deliberately contains no account, keychain, network, or storage-provider operations.
Index ¶
- Constants
- Variables
- func ExecutePrivatePublishIntent(ctx context.Context, ipa io.ReadSeeker, descriptor PreparedDescriptor, ...) (PublishReceipt, SensitiveLinks, error)
- func NormalizePrefix(raw string) (string, error)
- func PublicObjectURL(base, key string) (string, error)
- func Publish(ctx context.Context, ipa io.ReadSeeker, descriptor PreparedDescriptor, ...) (PublishReceipt, SensitiveLinks, error)
- func RedactedDirectInstallURL(links SensitiveLinks) string
- func RedactedInstallURL(links SensitiveLinks) string
- func Reverify(ctx context.Context, verifier Verifier, receipt PublishReceipt, ...) error
- func ValidateBucket(raw string) error
- func ValidateDescriptorForPublish(descriptor Descriptor) error
- func ValidateEndpoint(raw string) (*url.URL, error)
- func ValidatePrepareOptions(options PrepareOptions) error
- func ValidatePublicBaseURL(raw string) (*url.URL, error)
- type Access
- type App
- type Artifact
- type CodeSignatureVerification
- type CodeSignatureVerificationStatus
- type CorruptObjectReplacer
- type Descriptor
- type ExpectedIPA
- type HTTPVerifier
- type InspectOptions
- type Inspection
- type ObjectStore
- type Preparation
- type PrepareOptions
- type PrepareResult
- func PrepareIPA(file *os.File, size int64, options PrepareOptions) (result PrepareResult, resultErr error)
- func PrepareIPAContext(ctx context.Context, file *os.File, size int64, options PrepareOptions) (result PrepareResult, resultErr error)
- func PrepareIPAPath(ctx context.Context, inputRoot rootfs.Root, ipaPath string, ...) (PrepareResult, error)
- func PrepareIPAPathExact(ctx context.Context, inputRoot rootfs.Root, ipaPath string, ...) (PrepareResult, error)
- type PreparedApp
- type PreparedArtifact
- type PreparedBundle
- type PreparedCodeSignatureVerification
- type PreparedDescriptor
- type PreparedSigning
- type PrivatePublishDocument
- type PrivatePublishIntent
- type ProfileClass
- type PublishOptions
- type PublishReceipt
- type PutObject
- type ReceiptSigning
- type S3Store
- func (store *S3Store) CredentialSource() string
- func (store *S3Store) Ensure(ctx context.Context, input PutObject) (StoredObject, error)
- func (store *S3Store) PresignGet(ctx context.Context, key string, ttl time.Duration) (string, error)
- func (store *S3Store) ReplaceCorrupt(ctx context.Context, input PutObject) (StoredObject, error)
- type S3StoreConfig
- type SensitiveLinks
- type Signing
- type Source
- type StoredObject
- type Verifier
- type VerifyKind
- type VerifyRequest
Constants ¶
const ( ContentTypeIPA = "application/octet-stream" ContentTypeManifest = "application/xml" ContentTypeHTML = "text/html; charset=utf-8" )
const ( // CodeSignatureScopeCompleteMainApp is the exact verification scope required // before a prepared bundle may be published. CodeSignatureScopeCompleteMainApp = "complete-main-app-code-resources-entitlements-and-profile-certificate-binding" )
const ( // MaxIPABytes bounds synchronous inspection, hashing, and preparation work. MaxIPABytes int64 = 8 << 30 )
Variables ¶
var ( ErrNotEligible = errors.New("IPA metadata is not eligible for release-testing preparation") ErrBundleConflict = errors.New("distribution bundle conflicts with existing output") ErrIPAIdentityMismatch = errors.New("IPA snapshot does not match expected identity") )
var ( // ErrPrivatePublishLinkExpired means an immutable private install lease can // no longer be verified and must be replaced by a newly authorized run. ErrPrivatePublishLinkExpired = errors.New("private publication link expired") // ErrPrivatePublishProfileExpired means the signed payload is no longer // usable for publication and must be rebuilt under a new plan. ErrPrivatePublishProfileExpired = errors.New("private publication profile expired") // ErrPrivatePublishConflict means exact immutable local or remote evidence // conflicts with the saved publication intent. Retrying cannot repair it. ErrPrivatePublishConflict = errors.New("private publication intent conflict") // ErrImmutableObjectConflict means an existing object at an exact key does // not match the expected immutable content identity. ErrImmutableObjectConflict = errors.New("immutable object conflict") // ErrVerificationContentConflict means a successful fetch returned bytes or // representation metadata that conflict with the immutable expected object. // Retrying cannot make that exact destination safe to reuse. ErrVerificationContentConflict = errors.New("published object content conflict") )
var ErrObjectVerificationMismatch = errors.New("published object verification mismatch")
Functions ¶
func ExecutePrivatePublishIntent ¶
func ExecutePrivatePublishIntent(ctx context.Context, ipa io.ReadSeeker, descriptor PreparedDescriptor, options PublishOptions, intent PrivatePublishIntent) (PublishReceipt, SensitiveLinks, error)
ExecutePrivatePublishIntent converges exactly the saved destinations in IPA, manifest, page order. It never generates an identifier or presigned URL.
func NormalizePrefix ¶
func PublicObjectURL ¶
func Publish ¶
func Publish(ctx context.Context, ipa io.ReadSeeker, descriptor PreparedDescriptor, options PublishOptions) (PublishReceipt, SensitiveLinks, error)
func RedactedDirectInstallURL ¶
func RedactedDirectInstallURL(links SensitiveLinks) string
RedactedDirectInstallURL returns the exact non-secret itms-services URL form used in a public receipt.
func RedactedInstallURL ¶
func RedactedInstallURL(links SensitiveLinks) string
RedactedInstallURL returns the exact non-secret install-page URL form used in a public receipt. It is safe for logs and structured output.
func Reverify ¶
func Reverify(ctx context.Context, verifier Verifier, receipt PublishReceipt, links SensitiveLinks, now time.Time) error
func ValidateBucket ¶
func ValidateDescriptorForPublish ¶
func ValidateDescriptorForPublish(descriptor Descriptor) error
ValidateDescriptorForPublish is the canonical preparation-evidence gate for in-process consumers. It deliberately centralizes the exact verification scope so workflow and publisher code do not duplicate a security string.
func ValidatePrepareOptions ¶
func ValidatePrepareOptions(options PrepareOptions) error
ValidatePrepareOptions validates optional metadata before preparation opens or writes any filesystem path.
Types ¶
type CodeSignatureVerification ¶
type CodeSignatureVerification struct {
Status CodeSignatureVerificationStatus `json:"status"`
Scope string `json:"scope,omitempty"`
Reason string `json:"reason,omitempty"`
SignerCertificateSHA256Fingerprints []string `json:"signerCertificateSha256Fingerprints,omitempty"`
}
type CodeSignatureVerificationStatus ¶
type CodeSignatureVerificationStatus string
const ( CodeSignatureVerified CodeSignatureVerificationStatus = "verified" CodeSignatureInvalid CodeSignatureVerificationStatus = "invalid" CodeSignatureNotVerified CodeSignatureVerificationStatus = "not-verified" )
type CorruptObjectReplacer ¶
type CorruptObjectReplacer interface {
ReplaceCorrupt(context.Context, PutObject) (StoredObject, error)
}
type Descriptor ¶
type ExpectedIPA ¶
ExpectedIPA binds agent-driven preparation to an exact upstream artifact. SHA256 must be the lowercase hexadecimal digest of exactly SizeBytes bytes.
type HTTPVerifier ¶
type HTTPVerifier struct {
// contains filtered or unexported fields
}
func NewHTTPVerifier ¶
func NewHTTPVerifier(client *http.Client, timeout time.Duration) *HTTPVerifier
func NewHTTPVerifierWithEnvironmentTrust ¶
func NewHTTPVerifierWithEnvironmentTrust(timeout time.Duration) (*HTTPVerifier, error)
NewHTTPVerifierWithEnvironmentTrust builds a verifier that honors the same AWS_CA_BUNDLE trust override used by the S3 SDK for private endpoints.
func (*HTTPVerifier) Verify ¶
func (v *HTTPVerifier) Verify(ctx context.Context, verification VerifyRequest) error
type InspectOptions ¶
type Inspection ¶
type Inspection struct {
SchemaVersion string `json:"schemaVersion"`
Platform string `json:"platform"`
DistributionMethod string `json:"distributionMethod"`
App App `json:"app"`
Artifact Artifact `json:"artifact"`
Signing Signing `json:"signing"`
Preparation Preparation `json:"preparation"`
EmbeddedTargets []string `json:"embeddedTargets,omitempty"`
}
func InspectIPA ¶
func InspectIPA(file *os.File, size int64, options InspectOptions) (Inspection, error)
InspectIPA validates and reads deterministic metadata from an already-open regular IPA file. The file must remain open for the duration of the call.
func InspectIPAContext ¶
func InspectIPAContext(ctx context.Context, file *os.File, size int64, options InspectOptions) (Inspection, error)
type ObjectStore ¶
type Preparation ¶
type PrepareOptions ¶
type PrepareResult ¶
type PrepareResult struct {
BundlePath string `json:"bundlePath"`
Reused bool `json:"reused"`
Descriptor Descriptor `json:"descriptor"`
}
func PrepareIPA ¶
func PrepareIPA(file *os.File, size int64, options PrepareOptions) (result PrepareResult, resultErr error)
PrepareIPA validates an already-open IPA and publishes an immutable local bundle without replacing an existing destination.
func PrepareIPAContext ¶
func PrepareIPAContext(ctx context.Context, file *os.File, size int64, options PrepareOptions) (result PrepareResult, resultErr error)
func PrepareIPAPath ¶
func PrepareIPAPath(ctx context.Context, inputRoot rootfs.Root, ipaPath string, options PrepareOptions) (PrepareResult, error)
PrepareIPAPath opens a relative IPA path beneath inputRoot without following symlinks and prepares it with cancellation propagated through snapshotting and code-signature verification.
func PrepareIPAPathExact ¶
func PrepareIPAPathExact(ctx context.Context, inputRoot rootfs.Root, ipaPath string, expected ExpectedIPA, options PrepareOptions) (PrepareResult, error)
PrepareIPAPathExact is the agent-facing preparation seam. It snapshots a relative, no-follow input and rejects it before inspection or output writes unless the private snapshot exactly matches expected.
type PreparedApp ¶
type PreparedArtifact ¶
type PreparedBundle ¶
type PreparedBundle struct {
Descriptor PreparedDescriptor
DescriptorSHA256 string
DescriptorSize int64
IPA *os.File
IPASHA256 string
IPASize int64
}
func LoadPreparedBundle ¶
func LoadPreparedBundle(bundleDir string) (*PreparedBundle, error)
func LoadPreparedBundleContext ¶
LoadPreparedBundleContext reads a prepared bundle through an already-pinned root. The caller owns root and must retain it for the complete publication workflow so a lexical path replacement cannot select a different bundle.
type PreparedDescriptor ¶
type PreparedDescriptor struct {
SchemaVersion string `json:"schemaVersion"`
Platform string `json:"platform"`
DistributionMethod string `json:"distributionMethod"`
App PreparedApp `json:"app"`
Artifact PreparedArtifact `json:"artifact"`
Signing PreparedSigning `json:"signing"`
EmbeddedTargets []string `json:"embeddedTargets,omitempty"`
}
type PreparedSigning ¶
type PreparedSigning struct {
ProfileClass string `json:"profileClass"`
ProfileUUID string `json:"profileUuid"`
EmbeddedProfileSHA256 string `json:"embeddedProfileSha256"`
TeamID string `json:"teamId"`
ExpiresAt string `json:"expiresAt"`
DeviceCount int `json:"deviceCount"`
DeviceSetSHA256 string `json:"deviceSetSha256"`
ProfileCertificateSHA256Fingerprints []string `json:"profileCertificateSha256Fingerprints"`
CodeSignatureVerification PreparedCodeSignatureVerification `json:"codeSignatureVerification"`
ProfileIntegrityVerification PreparedCodeSignatureVerification `json:"profileIntegrityVerification"`
ProfileTrustVerification PreparedCodeSignatureVerification `json:"profileTrustVerification"`
}
func (*PreparedSigning) UnmarshalJSON ¶
func (signing *PreparedSigning) UnmarshalJSON(data []byte) error
type PrivatePublishDocument ¶
type PrivatePublishDocument struct {
StoredObject
Body []byte `json:"body"`
}
PrivatePublishDocument is an exact, persistable document publication. Body is encoded as base64 by encoding/json and belongs only in protected intent state because it may contain bearer URLs.
type PrivatePublishIntent ¶
type PrivatePublishIntent struct {
SchemaVersion string `json:"schemaVersion"`
CreatedAt time.Time `json:"createdAt"`
PageExpiresAt time.Time `json:"pageExpiresAt"`
DownloadExpiresAt time.Time `json:"downloadExpiresAt"`
CredentialLimit *time.Time `json:"credentialLimit,omitempty"`
Bucket string `json:"bucket"`
Prefix string `json:"prefix"`
URLTTL string `json:"urlTtl"`
DownloadGrace string `json:"downloadGrace"`
LinkID string `json:"linkId"`
Artifact StoredObject `json:"artifact"`
Manifest PrivatePublishDocument `json:"manifest"`
Page PrivatePublishDocument `json:"page"`
Links SensitiveLinks `json:"links"`
App PreparedApp `json:"app"`
Signing ReceiptSigning `json:"signing"`
}
PrivatePublishIntent contains every nondeterministic choice and generated byte required to converge a private publication after a crash. It must be persisted before ExecutePrivatePublishIntent is called.
func PreparePrivatePublishIntent ¶
func PreparePrivatePublishIntent(ctx context.Context, descriptor PreparedDescriptor, options PublishOptions) (PrivatePublishIntent, error)
PreparePrivatePublishIntent performs every private-publication choice and presign before any remote object write. Callers must durably persist the returned intent before execution.
func (PrivatePublishIntent) Clone ¶
func (intent PrivatePublishIntent) Clone() PrivatePublishIntent
Clone returns an independent intent suitable for validation tests and callers that must retain an immutable in-memory copy.
type ProfileClass ¶
type ProfileClass string
const ( ProfileClassUnknown ProfileClass = "unknown" ProfileClassDevelopment ProfileClass = "development" ProfileClassAdHoc ProfileClass = "ad-hoc" ProfileClassEnterprise ProfileClass = "enterprise" ProfileClassAppStore ProfileClass = "app-store" )
type PublishOptions ¶
type PublishReceipt ¶
type PublishReceipt struct {
SchemaVersion string `json:"schemaVersion"`
Endpoint string `json:"endpoint"`
DownloadEndpoint string `json:"downloadEndpoint,omitempty"`
PublicBaseURL string `json:"publicBaseUrl,omitempty"`
Region string `json:"region"`
AddressingStyle string `json:"addressingStyle"`
Access Access `json:"access"`
Bucket string `json:"bucket"`
Prefix string `json:"prefix"`
URLTTL string `json:"urlTtl,omitempty"`
DownloadGrace string `json:"downloadGrace,omitempty"`
Artifact StoredObject `json:"artifact"`
Manifest StoredObject `json:"manifest"`
Page StoredObject `json:"page"`
InstallURL string `json:"installUrl"`
DirectInstallURL string `json:"directInstallUrl"`
ExpiresAt *time.Time `json:"expiresAt,omitempty"`
Verified bool `json:"verified"`
App PreparedApp `json:"app"`
Signing ReceiptSigning `json:"signing"`
ReceiptPath string `json:"receiptPath,omitempty"`
LinkPath string `json:"linkPath,omitempty"`
}
type ReceiptSigning ¶
type ReceiptSigning struct {
ProfileClass string `json:"profileClass"`
ProfileUUID string `json:"profileUuid"`
EmbeddedProfileSHA256 string `json:"embeddedProfileSha256"`
TeamID string `json:"teamId"`
ProfileExpiresAt string `json:"profileExpiresAt"`
DeviceCount int `json:"deviceCount"`
DeviceSetSHA256 string `json:"deviceSetSha256"`
ProfileCertificateFingerprints []string `json:"profileCertificateSha256Fingerprints"`
ProfileIntegrityVerification PreparedCodeSignatureVerification `json:"profileIntegrityVerification"`
ProfileTrustVerification PreparedCodeSignatureVerification `json:"profileTrustVerification"`
CodeSignatureVerification PreparedCodeSignatureVerification `json:"codeSignatureVerification"`
}
func (ReceiptSigning) MatchesPrepared ¶
func (signing ReceiptSigning) MatchesPrepared(prepared PreparedSigning) bool
MatchesPrepared reports whether receipt signing facts exactly bind to a prepared descriptor without consuming raw device identifiers.
type S3Store ¶
type S3Store struct {
// contains filtered or unexported fields
}
func NewS3Store ¶
func (*S3Store) CredentialSource ¶
func (*S3Store) PresignGet ¶
func (*S3Store) ReplaceCorrupt ¶
ReplaceCorrupt conditionally replaces the exact object generation observed by a fresh HEAD. Matching metadata alone is insufficient after a full GET proved the body corrupt, while If-Match prevents overwriting a concurrent legitimate replacement.
type S3StoreConfig ¶
type SensitiveLinks ¶
type Signing ¶
type Signing struct {
ProfileClass ProfileClass `json:"profileClass"`
ProfileUUID string `json:"profileUuid,omitempty"`
TeamID string `json:"teamId,omitempty"`
ExpiresAt string `json:"expiresAt,omitempty"`
DeviceCount int `json:"deviceCount"`
DeviceSetSHA256 string `json:"deviceSetSha256,omitempty"`
EmbeddedProfileSHA256 string `json:"embeddedProfileSha256,omitempty"`
ProfileCertificateSHA256Fingerprints []string `json:"profileCertificateSha256Fingerprints,omitempty"`
Devices []string `json:"devices,omitempty"`
ProfileIntegrityVerification CodeSignatureVerification `json:"profileIntegrityVerification"`
ProfileTrustVerification CodeSignatureVerification `json:"profileTrustVerification"`
CodeSignatureVerification CodeSignatureVerification `json:"codeSignatureVerification"`
}
type StoredObject ¶
type VerifyRequest ¶
type VerifyRequest struct {
URL string
Kind VerifyKind
SHA256 string
SizeBytes int64
ContentType string
}