{"id":41589833,"url":"https://github.com/webex/webrtc-sframe","last_synced_at":"2026-01-24T09:12:24.109Z","repository":{"id":328819422,"uuid":"1096470728","full_name":"webex/webrtc-sframe","owner":"webex","description":null,"archived":false,"fork":false,"pushed_at":"2026-01-14T07:31:13.000Z","size":54,"stargazers_count":2,"open_issues_count":5,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-01-14T11:23:44.226Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/webex.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-14T13:27:30.000Z","updated_at":"2025-12-15T02:43:54.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/webex/webrtc-sframe","commit_stats":null,"previous_names":["webex/webrtc-sframe"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/webex/webrtc-sframe","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webex%2Fwebrtc-sframe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webex%2Fwebrtc-sframe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webex%2Fwebrtc-sframe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webex%2Fwebrtc-sframe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/webex","download_url":"https://codeload.github.com/webex/webrtc-sframe/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webex%2Fwebrtc-sframe/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28722333,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-24T08:27:05.734Z","status":"ssl_error","status_checked_at":"2026-01-24T08:27:01.197Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-24T09:12:24.056Z","updated_at":"2026-01-24T09:12:24.102Z","avatar_url":"https://github.com/webex.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# WebRTC SFrame Integration\n\nThis document describes how to integrate SFrame (Secure Frame) encryption into WebRTC applications. SFrame provides end-to-end media security that works even when media flows through untrusted servers or intermediaries.\n\n## Overview\n\nSFrame encryption can be applied at two different levels:\n- **Per-frame**: Encrypts complete video/audio frames before packetization\n- **Per-packet**: Encrypts individual RTP packets after packetization\n\nBoth approaches offer strong security guarantees, with per-packet providing finer granularity and per-frame offering better performance characteristics.\n\n## JavaScript API\n\n### SFrame Modes\n\n```javascript\n// Available modes for SFrame encryption\nconst SFrameMode = {\n    \"per-frame\",   // Encrypt at frame level\n    \"per-packet\"   // Encrypt at packet level\n};\n```\n\n### Basic Usage\n\nAssumption; JS API usage after recent W3C meeting.\n\n```javascript\n// Create peer connection\nconst peerConnection = new RTCPeerConnection();\n\n// Add video track\nconst videoTransceiver = peerConnection.addTransceiver(\"video\", {\n  direction: \"sendonly\"\n});\n\n// Configure SFrame options\nconst sframeOptions = {\n  mode: \"per-packet\"  // or \"per-frame\"\n};\n\n// Apply SFrame transform\nvideoTransceiver.sender.transform = new SFrameTransform(sframeOptions);\n```\n\n### Key Points\n\n- SFrame can be configured independently for each media track\n- Both sender and receiver need compatible SFrame configurations\n- The API maintains backward compatibility with non-SFrame endpoints\n\n## C++ API\n\nThe SFrame API design provides transformer injection at the sender and receiver level, following the JavaScript API pattern:\n\n```javascript\nvideoTransceiver.sender.transform = new SFrameTransform(sframeOptions);\n```\n\nFollowing this design proposal principles, the `SetSFrameTransformer` method will be exposed through the `RTPSenderInterface` and `RTPReceiverInterface` to provide this granular control and maintain consistency with the JavaScript API surface.\n\n### Core Interfaces\n\n#### SFrameMode Enumeration\n\nDefines the granularity at which SFrame encryption is applied to media data.\n\n`api/sframe/sframe_options.h`\n```cpp\nenum SFrameMode {\n  kPerFrame,   // Frame-level encryption\n  kPerPacket   // Packet-level encryption\n};\n```\n\n#### SFrameOptions Configuration\n\nConfiguration structure that defines SFrame encryption behavior.\n\n`api/sframe/sframe_options.h`\n```cpp\nstruct SFrameOptions {\n    SFrameMode mode;\n    // Additional options can be added here in the future\n};\n```\n\n#### SFrameTransformerHost Interface\n\nThe `SFrameTransformerHost` interface provides a unified way to inject SFrame transformers into WebRTC components. This interface will be implemented by RTP senders and receivers to enable SFrame encryption and decryption capabilities.\n\n`api/sframe/sframe_transformer_interface.h`\n```cpp\nclass SFrameTransformerHost {\n public:\n  virtual ~SFrameTransformerHost() = default;\n\n  // Configures SFrame transformer with specified options\n  virtual void SetSFrameTransformer(\n      scoped_refptr\u003cSFrameTransformerInterface\u003e sframe_transformer,\n      SFrameOptions options) = 0;\n\n  // Retrieves currently configured transformer (may return nullptr)\n  virtual scoped_refptr\u003cSFrameTransformerInterface\u003e GetSFrameTransformer() = 0;\n};\n```\n\n#### SFrame Transformer Interface\n\nThe main interface for implementing SFrame encryption/decryption:\n\n`api/sframe/sframe_transformer_interface.h`\n```cpp\nclass SFrameTransformerInterface : public RefCountInterface {\n public:\n  virtual ~SFrameTransformerInterface() = default;\n\n  // Configure encryption keys\n  virtual void SetEncryptionKey(/*Keys*/) = 0;\n\n  // Transform media data (encrypt or decrypt)\n  virtual void Transform(CopyOnWriteBuffer buffer) = 0;\n};\n```\n\n#### Integration with RTP Senders/Receivers\n\nRTP interfaces inherit from `SFrameTransformerHost` to support SFrame injection:\n\n`api/rtp_sender_interface.h`\n```cpp\nclass RtpSenderInterface : public SFrameTransformerHost {\n public:\n  // Default implementation, actuall implementation will be done by classes inheriting RtpSenderInterface\n  void SetSFrameTransformer(\n      scoped_refptr\u003cSFrameTransformerInterface\u003e sframe_transformer,\n      SFrameOptions options) {};\n};\n```\n\n`api/rtp_receiver_interface.h`\n```cpp\nclass RtpReceiverInterface : public SFrameTransformerHost {\n public:\n // Default implementation, actuall implementation will be done by classes inheriting RtpReceiverInterface\n  void SetSFrameTransformer(\n      scoped_refptr\u003cSFrameTransformerInterface\u003e sframe_transformer,\n      SFrameOptions options) {};\n};\n```\n\n### Cisco SFrame Library\n\nWebRTC will provide a built-in SFrame implementation using the [Cisco SFrame](https://github.com/cisco/sframe) library.\n\n#### Encrypt or decrypt\n\nDecision whether SFrameTransformer should perform encryption or decryption will be defined by the `SFrameRole` parameter.\n\n`api/sframe/sframe_transformer.h`\n```cpp\nenum SFrameRole {\n  Encrypt,\n  Decrypt\n};\n```\n\n#### Supported Cipher Suites\n\n`api/sframe/sframe_transformer.h`\n```cpp\nenum SFrameCipherSuite {\n  AES_128_CTR_HMAC_SHA256_8,   // AES-128-CTR with 8-byte auth tag\n  AES_128_CTR_HMAC_SHA256_64,  // AES-128-CTR with 64-byte auth tag\n  AES_128_CTR_HMAC_SHA256_32,  // AES-128-CTR with 32-byte auth tag\n  AES_128_GCM_SHA256_128,      // AES-128-GCM with 128-bit auth tag\n  AES_256_GCM_SHA512_128       // AES-256-GCM with 128-bit auth tag\n};\n```\n\n#### RTCSFrameTransformer\n\n`RTCSFrameTransformer` will leverage [Cisco SFrame](https://github.com/cisco/sframe) library to implement SFrame encryption/decryption.\n\n`modules/sframe/rtc_sframe_transformer.h`\n```cpp\nclass RTCSFrameTransformer : public SFrameTransformerInterface {\n public:\n  explicit RTCSFrameTransformer(SFrameRole role, SFrameCipherSuite cipher_suite);\n\n  void SetEncryptionKey(std::string key) override {\n    // Update keys in SFrame Context\n  }\n\n  // Transform media data (encrypt or decrypt)\n  void Transform(CopyOnWriteBuffer buffer) override {\n    // role == SFrameRole::Encrypt ? Encrypt(buffer) : Decrypt(buffer);\n  }\n\nprivate:\n  void Encrypt(CopyOnWriteBuffer buffer);\n\n  void Decrypt(CopyOnWriteBuffer buffer);\n};\n```\n\n#### RTCSFrameTransformer Factory\n\n`RTCSFrameTransformer` creation will be possible throught the factory method exposed from the libwebrtc API.\n\n`api/sframe/sframe_transformer_factory.h`\n```cpp\nscoped_refptr\u003cSFrameTransformerInterface\u003e CreateSFrameTransformer(SFrameRole role, SFrameCipherSuite cipher_suite);\n```\n\n```cpp\nscoped_refptr\u003cSFrameTransformerInterface\u003e CreateSFrameTransformer(SFrameRole role, SFrameCipherSuite cipher_suite)\n{\n  return make_ref_counted\u003cRTCSFrameTransformer\u003e(role, cipher_suite);\n}\n```\n\n### Complete Usage Example\n\n```cpp\n// Create peer connection\nRTCPeerConnection pc;\n\n// Add video transceiver\nauto transceiver = pc.AddTransceiver(\"video\");\n\n// Create SFrame transformer for encryption\nauto sframe_transformer = CreateSFrameTransformer(SFrameRole::kEncrypt, \n    SFrameCipherSuite::AES_128_GCM_SHA256_128);\n\n// Configure for per-packet encryption\nSFrameOptions options;\noptions.mode = SFrameMode::kPerPacket;\n\n// Apply to sender\ntransceiver-\u003esender()-\u003eSetSFrameTransformer(sframe_transformer, options);\n\nsframe_transformer-\u003eSetEncryptionKey(\"XYZ\");\n```\n\n## Additional Resources\n\n### Related Specifications\n- [SFrame Protocol](https://datatracker.ietf.org/doc/draft-omara-sframe/) - The underlying SFrame specification\n- [WebRTC API](https://w3c.github.io/webrtc-pc/) - W3C WebRTC specification\n- [Cisco SFrame Library](https://github.com/cisco/sframe) - Reference implementation\n- [RTP SFrame](https://datatracker.ietf.org/doc/draft-ietf-avtcore-rtp-sframe)\n- [Encoded Transform](https://www.w3.org/TR/webrtc-encoded-transform)\n\n**Open Questions:**\n- Should we use `CopyOnWriteBuffer` or rather `ArraView\u003cuint8_t\u003e` for transformation\n- Do we need on libwebrtc level to have single \"Transformer\" interface. \n  Maybe it's fine to split it into encrypter and decrypter, and let browser level code decide which to create.\n  Instead of having an generic `RTCSFrameTransformer` with `SFrameRole` in the parameter, we could create a separate objects for handling encryption and decryption.\n\n```cpp\n  class RTCSFrameEncryptor : public SFrameTransformerInterface {\n  public:\n    explicit RTCSFrameEncryptor(SFrameCipherSuite cipher_suite);\n    // Implementation handles the crypto details\n  };\n\n  class RTCSFrameDecryptor : public SFrameTransformerInterface {\n  public:\n    explicit RTCSFrameDecryptor(SFrameCipherSuite cipher_suite);\n    // Implementation handles the crypto details\n  };\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwebex%2Fwebrtc-sframe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwebex%2Fwebrtc-sframe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwebex%2Fwebrtc-sframe/lists"}