Small Go interfaces and value types through which protocol libraries reach the security services an application provides.
The services are TLS profile selection, security events, keys and roles, network dialing, crypto policy and a durable state store. A library takes these as optional configuration; the application implements them. It was written for SigmaM2M, a oneM2M platform, whose protocol libraries use it and whose server implements the seams. Ready-made implementations cover the plain case (stores, a slog auditor, a policy from allow lists, key files, CRL and OCSP checks). Standard library only, except the revocation package (golang.org/x/crypto/ocsp); no cgo.
| Seam | Types | What a library does with it |
|---|---|---|
| TLS profile | TLSClient, TLSServer, TLSListener, TLSSelection, TLSServerProfile, StdTLS, TLSNamedClient, ServerNameFor |
secures its connections, checking the server certificate against the client's own name or else the host it dialled; a device emulation narrows the cipher suites through TLSServerProfile |
| Idle-link keepalive | Keepalive, KeepaliveConn, SetKeepalive |
registers its protocol's keepalive (DNP3: REQUEST_LINK_STATUS) on a connection whose profile needs traffic before a timed key update (IEC 62351-3) |
| Audit | SecurityEvent, Auditor, AuditFunc |
reports refusals and limits to the application's security log |
| Keys | Identity, KeySource, CertValidator, CertValidatorFunc |
asks for the current key and certificate (IEC 62351-9 renewal stays in the application); checks a peer certificate's validity and revocation |
| Roles (IEC 62351-8) | RoleAuthority, AccessToken, RoleEntry, RoleGrant, RoleRequest, RoleScope, SequenceStore, NewRoleAuthority, CertificateRoleAuthority, ErrRevoked |
hands a peer's certificate (or its token) to the authority, gets the roles granted here, and decides what they permit in its protocol |
| Network | Dialer, DialerFunc |
opens outgoing connections through the application's egress rules |
| Crypto policy | CryptoPolicy, CryptoPolicyFunc, Algorithm |
asks before using an algorithm (ITSAR, FIPS-style or local policy) |
| State | Store, ErrNotStored |
keeps a small value (wrapped keys, sequence numbers) durably |
Every seam is optional. A library documents what it does when one is nil: usually the plain standard-library behaviour, or refusing only the feature that needs it.
What the module does not do: it implements none of the IEC 62351 parts it names. The standard numbers only say which service a seam stands for. The ready-made implementations below cover the plain case; anything more (an enrolment service, a policy engine, a security information and event management system) is the application's.
| Seam | Implementation | What it does |
|---|---|---|
| State | MemoryStore, FileStore |
in memory; or one JSON file, written to a temporary file, synced and renamed (mode 0600) |
| Roles | MemorySequences |
a SequenceStore in memory |
| Audit | SlogAuditor, MultiAuditor |
security events to a slog.Logger (failures at Warn, every field an attribute); fan-out to several auditors |
| Crypto policy | PolicyRules |
allow lists per algorithm kind, denied names, minimum key and tag sizes, minimum RSA and elliptic-curve key sizes (ErrPolicy) |
| Keys | StaticKeySource, FileKeySource |
a fixed identity; or a PEM certificate chain and key read from files and read again when they change |
| Certificate checks | ValidityPeriod, AllValidators, revocation.New |
validity period; several validators in turn; the revocation package: CRLs given or fetched from the distribution points, OCSP, with caching, soft or strict (ErrRevoked, ErrUnchecked) |
The revocation package is the only part with a dependency beyond the
standard library (golang.org/x/crypto/ocsp); programs that do not import
it do not need that module.
The seams are for libraries; an application chooses what goes behind them. Compared in October 2026:
| iotsec | crypto/tls Config passed to each library |
golang.org/x/crypto/ocsp directly | |
|---|---|---|---|
| TLS for a protocol library | a TLSClient/TLSServer the application provides; StdTLS wraps a crypto/tls config |
the same config, but each library has its own option and none can take a non-standard TLS stack | n/a |
| Keepalive, audit, roles, policy, keys, state, egress | one interface each, shared by the protocol libraries | not covered | not covered |
| Revocation | revocation: CRL (given or fetched) and OCSP with caching, as a CertValidator |
VerifyPeerCertificate hooks written per program |
request and response encoding only; fetching, caching and policy are the caller's |
Pick iotsec when a program uses several of the cB-Sigma protocol
libraries and wants their security in one place. A program that uses one
library with plain TLS needs nothing from it beyond StdTLS. A search
of pkg.go.dev for "62351" (October 2026) found five modules: IEC 62351-3
TLS profiles inside protocol packages (github.com/dscsystems/go-iec61850
and an example of github.com/otfabric/go-iec104), the security
extension of the iec60870 library and two copies of tlsx, a crypto/tls
fork; none offers seams shared across protocol libraries. Pick
go-iec61850's profile when you use that library.
go get github.com/cB-Sigma/iotsec@latestRequires Go 1.24.0 or later (the go line of go.mod).
An application without a security log of its own can send a library's
security events to slog (from ExampleAuditFunc in example_test.go):
log := slog.New(slog.NewTextHandler(os.Stdout, nil))
var a iotsec.Auditor = iotsec.AuditFunc(func(ctx context.Context, e iotsec.SecurityEvent) {
log.WarnContext(ctx, "security event", "event", e.Event, "outcome", e.Outcome, "subject", e.Subject)
})
// A library calls it like this:
a.RecordSecurity(context.Background(), iotsec.SecurityEvent{
Event: "dnp3_broadcast_refused", Outcome: iotsec.OutcomeFailure, Subject: "rtu-9"})
// level=WARN msg="security event" event=dnp3_broadcast_refused outcome=failure subject=rtu-9A library that accepts the seams is configured the same way, for example a
TLS client from crypto/tls: TLS: iotsec.StdTLS{Config: tlsConfig}.
API reference: pkg.go.dev/github.com/cB-Sigma/iotsec.
The module is a single package, iotsec; the seams are listed above.
The cB-Sigma protocol libraries (from their source, October 2026):
| Library | Seams used |
|---|---|
| dnp3 | TLS client and server, keepalive, audit, roles, dialer |
| iec60870 | TLS client and server, keepalive, audit, certificate roles, dialer |
| dlms | state store (security material, invocation counters), crypto policy, audit |
| iec61850 | TLS client and server, keepalive, audit, keys (KeySource and CertValidator behind ACSE authentication and end-to-end security) |
| iec62351 | TLS client, keepalive, audit, certificate roles |
| cctv (ONVIF) | crypto policy, asked before an MD5 HTTP digest challenge is answered |
go vet ./...
go test -race ./...The test certificates are generated at run time; the module contains no keys. Interop testing does not apply: the module has no protocol of its own. The revocation tests run a CA, a CRL distribution point and an OCSP responder (golang.org/x/crypto/ocsp) in process; the validator has not yet been run against a public CA's responders.
- iotcrypto: cryptographic building blocks (AES-CCM, KMAC, brainpool, Zigbee key establishment, SCRAM) used by the same protocol libraries.
v0.x. The API may change before v1. The interfaces are kept small on purpose; a method is added only when a library cannot do with what is here.
See CONTRIBUTING.md.
Please report vulnerabilities privately; see SECURITY.md.
Apache-2.0 (see LICENSE and NOTICE), Copyright 2026 Abhinav Gautam.