fleet/ee/server/integrationtest/condaccess/suite.go
Victor Lyuboslavsky 7c9c5b9a2e
Okta SCEP endpoint (#34721)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #34542

- Added SCEP endpoint for issuing certs for conditional access for Okta.
Functionally similar to host identity and Apple MDM SCEP endpoints.
- Changes file will be added later (this is a sub-task of the feature).
- A standard SCEP payload can be used to get a cert to an Apple device:

```
<!-- SCEP Configuration -->
<dict>
	<key>PayloadContent</key>
	<dict>
		<key>URL</key>
		<string>https://myfleet.example.com/api/fleet/conditional_access/scep</string>
		<key>Challenge</key>
		<string>ENROLLMENT_SECRET</string>
		<key>Keysize</key>
		<integer>2048</integer>
		<key>Key Type</key>
		<string>RSA</string>
		<key>Key Usage</key>
		<integer>5</integer>
              <key>ExtendedKeyUsage</key>
              <array>
                  <string>1.3.6.1.5.5.7.3.2</string>
              </array>
		<key>Subject</key>
		<array>
			<array>
				<array>
					<string>CN</string>
					<string>Fleet conditional access for Okta</string>
				</array>
			</array>
		</array>
		<key>SubjectAltName</key>
		<dict>
			<key>uniformResourceIdentifier</key>
			<array>
				<string>urn:device:apple:uuid:%HardwareUUID%</string>
			</array>
		</dict>
		<key>Retries</key>
		<integer>3</integer>
		<key>RetryDelay</key>
		<integer>10</integer>
              <!-- ACL for browser access -->
              <key>AllowAllAppsAccess</key>
              <true/>
              <!-- Set true for Safari access. Set false if Safari support not needed. -->
              <key>KeyIsExtractable</key>
              <false/>
	</dict>
	<key>PayloadDescription</key>
	<string>Configures SCEP for Fleet conditional access for Okta certificate</string>
	<key>PayloadDisplayName</key>
	<string>Fleet conditional access SCEP</string>
	<key>PayloadIdentifier</key>
	<string>com.fleetdm.conditional-access-scep</string>
	<key>PayloadType</key>
	<string>com.apple.security.scep</string>
	<key>PayloadUUID</key>
	<string>B2C3D4E5-F6A7-4B6C-9D8E-0F1A2B3C4D5E</string>
	<key>PayloadVersion</key>
	<integer>1</integer>
</dict>
```

# Checklist for submitter

## Testing

- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually

## Database migrations

- [x] Ensured the correct collation is explicitly set for character
columns (`COLLATE utf8mb4_unicode_ci`).



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

## New Features
* Adds Conditional Access SCEP certificate enrollment support, enabling
hosts to obtain device identity certificates through secure certificate
enrollment protocol endpoints.
* Implements rate limiting for certificate enrollment requests to
prevent abuse.

## Tests
* Adds comprehensive integration tests for Conditional Access SCEP
functionality, including certificate operations, rate limiting
validation, and edge cases.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-11-06 17:07:17 -06:00

67 lines
1.9 KiB
Go

package condaccess
import (
"os"
"testing"
"github.com/fleetdm/fleet/v4/server/config"
"github.com/fleetdm/fleet/v4/server/datastore/redis/redistest"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/fleetdm/fleet/v4/server/service"
"github.com/fleetdm/fleet/v4/server/service/integrationtest"
"github.com/go-kit/kit/log"
kitlog "github.com/go-kit/log"
"github.com/stretchr/testify/require"
)
type Suite struct {
integrationtest.BaseSuite
}
func SetUpSuite(t *testing.T, uniqueTestName string) *Suite {
return SetUpSuiteWithConfig(t, uniqueTestName, nil)
}
func SetUpSuiteWithConfig(t *testing.T, uniqueTestName string, configModifier func(cfg *config.FleetConfig)) *Suite {
// Note: t.Parallel() is called when MySQL datastore options are processed
license := &fleet.LicenseInfo{
Tier: fleet.TierPremium,
}
ds, fleetCfg, fleetSvc, ctx := integrationtest.SetUpMySQLAndService(t, uniqueTestName, &service.TestServerOpts{
License: license,
Pool: redistest.SetupRedis(t, t.Name(), false, false, false),
})
// Apply config modifications
if configModifier != nil {
configModifier(&fleetCfg)
}
logger := log.NewLogfmtLogger(os.Stdout)
condAccessSCEPDepot, err := ds.NewConditionalAccessSCEPDepot(kitlog.With(logger, "component", "conditional-access-scep-depot"), &fleetCfg)
require.NoError(t, err)
users, server := service.RunServerForTestsWithServiceWithDS(t, ctx, ds, fleetSvc, &service.TestServerOpts{
License: license,
FleetConfig: &fleetCfg,
Logger: logger,
ConditionalAccess: &service.ConditionalAccess{
SCEPStorage: condAccessSCEPDepot,
},
})
s := &Suite{
BaseSuite: integrationtest.BaseSuite{
Logger: logger,
DS: ds,
FleetCfg: fleetCfg,
Users: users,
Server: server,
},
}
integrationtest.SetUpServerURL(t, ds, server)
s.BaseSuite.Token = s.BaseSuite.GetTestAdminToken(t)
return s
}